Repository/UnitOfWork 添加 throws Cannot insert the value NULL into column 错误

Repository/UnitOfWork Add throws Cannot insert the value NULL into column error

我正在开发一个从 REST API 获取数据的应用程序。我正在针对具体的 class 解析 json,然后将该部分逐步解析为 UpdateInsert(取决于该行是否存在)进入 SQL 数据库。其中一部分是创建一个带有 SkillIdAccountId 的唯一标识符列,恰当地命名为 AccountSkillId。我相信我已经将问题追溯到 RepositoryAdd 部分,因为 Commit 有效,但 Add 无效。

Add 就像我传递的实体是空的,但是当我在本地查看它时,它表明它不是空的:

这是我的业务层中尝试

的代码
    public void GetSkills()
    {
        var dataContext = new LivePersonContext(ConfigurationWrapper.DataConnectionString);
        var apiRequest = new OAuthRequest();
        var builder = new StringBuilder("");

        using (dataContext)
        {
            var uow = new UnitOfWork(dataContext);
            var accountCredentialIds = uow.Accounts.GetAll().Select(c => c.AccountID).ToList();

            foreach (var a in accountCredentialIds)
            {
                var account = a;
                try
                {
                    builder.Clear();
                    var consumerKey = uow.Accounts.GetById(account).ConsumerKey;
                    var consumerSecret = uow.Accounts.GetById(account).ConsumerSecret;
                    var token = uow.Accounts.GetById(account).Token;
                    var tokenSecret = uow.Accounts.GetById(account).TokenSecret;
                    builder.AppendFormat(ConfigurationWrapper.SkillsUri, account);
                    var uri = builder.ToString();

                    var response = apiRequest.OauthRequestResponse(uri, consumerKey, consumerSecret, token,
                        tokenSecret);
                    if (response != null)
                    {
                        using (var reader = new StreamReader(response.GetResponseStream()))
                        {
                            var json = reader.ReadToEnd();
                            var jsonObj = JsonConvert.DeserializeObject<List<Entity.Skills>>(json);

                            var currentSkillData = uow.SkillMeta.GetAll().Select(c => c.AccountSkillId).ToList();

                            foreach (var item in jsonObj)
                            {
                                if (item.id != null)
                                {
                                    var itemId = int.Parse(item.id);
                                    var string2 = item.id + account;


                                    var accountSkillId = int.Parse(string2);

                                    if (currentSkillData.Contains(accountSkillId))
                                    {
                                        var skillUpdate = uow.SkillMeta.GetById(accountSkillId);

                                       // skillUpdate.AccountSkillID = int.Parse(accountSkillId);
                                        //skillUpdate.AccountID = account;
                                        //skillUpdate.SkillID = int.Parse(item.id);
                                        skillUpdate.Name = item.name;
                                        skillUpdate.IsDefault = item.isDefault;
                                        skillUpdate.Description = item.description;
                                        uow.Commit();
                                    }
                                    else
                                    {
                                        var addSkill = new lp_Skill_Meta
                                        {
                                            AccountSkillId = accountSkillId,
                                            AccountId = account,
                                            SkillId = itemId,
                                            Name = item.name,
                                            IsDefault = item.isDefault,
                                            Description = item.description,

                                            //TODO: Verify that they are only ever passing single values
                                            Rel = item.links[0].rel,
                                            Href = item.links[0].href
                                        };


                                            uow.SkillMeta.Add(addSkill);
                                            uow.Commit();
                                        }
                                }
                            }
                        }
                    }
                }
                catch (Exception exception)
                {
                    var lEngine = new LoggerEngine{Logger = _logger};
                    lEngine.Log("ERROR: " + exception);
                }
            }
        }
    }

这是我的知识库摘要 Class

 public abstract class Repository<T> : IRepository<T>
    where T : class
{
    protected  DbSet<T> _objectSet;

    public Repository(BaseContext context)
    {
        _objectSet = context.Set<T>();
    }
    #region IRepository<T> Members

    public abstract T GetById(object id);

    public IEnumerable<T> GetAll()
    {
        return _objectSet;
    }

    public IEnumerable<T> Query(Expression<Func<T, bool>>  filter)
    {
        return _objectSet.Where(filter);
    }

    public void Add(T entity)
    {
        _objectSet.Add(entity);

    }

    public void Remove(T entity)
    {
        _objectSet.Remove(entity);
    }
    #endregion
}

BaseContext 在我的 DAL

中是一个 DbContext 抽象

这是我要添加到我的数据库中的实体

public class lp_Skill_Meta
{
    [Key]  
    public long AccountSkillId { get; set; }

    public int AccountId { get; set; }
    public int SkillId { get; set; }
    public string Name { get; set; }
    public bool IsDefault { get; set; }
    public string Description { get; set; }
    public string Rel { get; set; }
    public string Href { get; set; }
}

这是数据库的架构:

CREATE TABLE [dbo].[lp_Skill_Meta](
    [AccountSkillId] [bigint] NOT NULL,
    [AccountId] [int] NOT NULL,
    [SkillId] [int] NOT NULL,
    [Name] [varchar](250) NULL,
    [IsDefault] [bit] NULL,
    [Description] [varchar](max) NULL,
    [Rel] [varchar](50) NULL,
    [Href] [varchar](250) NULL
) ON [PRIMARY]

正如您在图片中看到的,当我将实体传递到添加并尝试提交更改时,实体不是空的。但我仍然得到:

Cannot insert the value NULL into column AccountSkillId, table `DatabaseName.dbo.lp_Skill_Meta'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated.

我已经盯着这个看了几个小时了,搜索了又搜索,但没有看到这种情况(不是说不存在),但任何帮助都会很棒。

更新: 基于 SQL Trace hat tip to Jeff below in the comments here is the query that EF is trying to 运行

exec sp_executesql N'INSERT [dbo].[lp_Skill]([AccountId], [SkillId], [Name], [IsDefault], [Description], [Rel], [Href]) VALUES (@0, @1, @2, @3, @4, @5, @6) SELECT [AccountSkillId] FROM [dbo].[lp_Skill] WHERE @@ROWCOUNT > 0 AND [AccountSkillId] = scope_identity()' ,N'@0 int,@1 int,@2 nvarchar(max) ,@3 bit,@4 nvarchar(max) ,@5 nvarchar(max) ,@6 nvarchar(max) ' ,@0=10740014,@1=6,@2=N'Abusers',@3=0,@4=N'Abusers',@5=N'self',@6=N'https://sales.liveperson.net/api/account/10740014/skills/6'

AccountSkillId 不是数据库中的标识列,所以这就是它抛出 NULL 的原因。现在开始搜索如何让它停止将该列标记为身份...

针对这个问题:Cannot insert the value NULL into column in ASP.NET MVC Entity Framework

答案归结为将 [DatabaseGenerated(DatabaseGeneratedOption.None)] 添加到我的 Entity 运行中就像一个魅力。向@JeffTreuting 大喊大叫,因为他用 SQL Trace 为我指明了正确的方向。老实说,我什至没有想过。再次感谢大家!

    public class lp_Skill
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public long AccountSkillId { get; set; }

    public int AccountId { get; set; }
    public int SkillId { get; set; }
    public string Name { get; set; }
    public bool IsDefault { get; set; }
    public string Description { get; set; }
    public string Rel { get; set; }
    public string Href { get; set; }
}