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,然后将该部分逐步解析为 Update
或 Insert
(取决于该行是否存在)进入 SQL 数据库。其中一部分是创建一个带有 SkillId
和 AccountId
的唯一标识符列,恰当地命名为 AccountSkillId
。我相信我已经将问题追溯到 Repository
的 Add
部分,因为 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; }
}
我正在开发一个从 REST API 获取数据的应用程序。我正在针对具体的 class 解析 json,然后将该部分逐步解析为 Update
或 Insert
(取决于该行是否存在)进入 SQL 数据库。其中一部分是创建一个带有 SkillId
和 AccountId
的唯一标识符列,恰当地命名为 AccountSkillId
。我相信我已经将问题追溯到 Repository
的 Add
部分,因为 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; }
}