我正在使用EF CTP 4.我有一个简单的控制台应用程序(用于测试目的),它使用EF将一些数据插入SQL数据库。
我遇到了插入物品的问题
using(var context = GetContext())
{
BOB b = new BOB();
b.Id = 1;
context.Bobs.Add(b);
context.SaveChanges();
}
它抛出错误: {“无法将值NULL插入列'Id',表'TestDB.dbo.BOB';列不允许空值.INSERT失败。\ r \ n语句已终止。“}
表只有1个字段 Id int NOT NULL 这是主键,不是自动递增的Id。
在创建DataContext时,我有这个配置,肯定会被解雇。
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<BOB>().HasKey(b => b.Id);
builder.Entity<BOB>().MapSingleType().ToTable("BOB");
}
我还预先填充了这个表,然后通过调试器能够通过 watch 加载这个BOB对象...所以我真的很难过,因为能够加载我的BOB表明一切都是正确的...但是在插入一个新的时它会崩溃...
答案 0 :(得分:68)
我在这里有同样的问题,这真的是一个丑陋的解决方案。
[Key]
public Int64 PolicyID { get; set; }
这不是自动生成的数字
然后我遇到了同样的错误。
EF Code First CTP5
申请后:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Int64 PolicyID { get; set; }
然后它会起作用。
答案 1 :(得分:28)
您是否尝试过明确指定StoreGeneratedPattern
?
modelBuilder.Entity<BOB>()
.HasKey(p => p.Id)
.Property(p => p.Id)
.StoreGeneratedPattern = StoreGeneratedPattern.None;
builder.Entity<BOB>().MapSingleType().ToTable("BOB");
答案 2 :(得分:26)
我正在使用EF 4.1,Model First并遇到了这个问题。这就是我解决它的方法:
使用模型设计器表面时,在创建实体时,必须定义“键”属性,默认为Id,int32。
在我的情况下,我选择使用Guids作为Id,所以我将int32切换为Guid。但是如果你在创建实体后检查这个Id,我看到Id的'StoreGeneratedPattern'选择了'identity'。起初我不认为这是一个问题,但是当我检查用于插入数据库的SQL时,它有点奇怪,因为它没有发送我的Id。的令人沮丧!强>
但是一旦我回去并将'StoreGeneratedPattern'从'identity'更改为'none',重新生成数据库并重建项目,这个奇怪的 {“无法将值NULL插入列'Id',表'TestDB.dbo.BOB';列不允许空值.INSERT失败。\ r \ n语句已终止。“} 停止发生。
仅供参考 - 在查看sql之后,似乎如果你为'StoreGeneratedPattern'选择了'identity',EF会将对象保存到db(没有Id),然后立即取回身份并将其保存回来你的对象。即“StoreGeneratedPattern”的选择依赖于数据库生成您的ID,不您的代码!
答案 3 :(得分:3)
当我在db模式中的受尊重列(标识列)上缺少主键时,发生了这种情况。 我使用SSMS导出工具和创建新数据库在SQL服务器之间导出数据,但没有意识到它只导出数据而没有密钥。
答案 4 :(得分:1)
您也可以使用
modelBuilder.Entity<BOB>()
.HasKey(p => p.Id)
.Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
builder.Entity<BOB>().MapSingleType().ToTable("BOB");
答案 5 :(得分:0)
我知道这个问题在某种程度上是过时的,并且已经找到了一个公认的解决方案,但我认为如果我分享我的发现会有用。
我今天遇到此错误,因为我使用的是同一DataContext
的两个不同实例。我正在创建一个带有一些属性的新模型 - 这些属性的值是使用DataContext
的一个实例从数据库加载的,然后我试图将这个新创建的模型推送到数据库调用第一Add()
和然后在SaveChanges()
的其他实例上DataContext
。在我开始使用相同的实例来获取属性的值并实际添加和保存新对象之后 - 一切都开始工作了。
答案 6 :(得分:0)
我遇到了类似的情况,但在我的情况下,即使设置Identity
到off
也没有帮助。
问题与主键有关,我错过了在主体模型中添加。
以下是生成模型的脚本:
CREATE TABLE [im].[SomeGroup]
(
[Id] INT NOT NULL IDENTITY(1,1), -- this is mandatory for EF
[OtherGroupId] INT NOT NULL,
[Title] NVARCHAR(512) NOT NULL
)
上面的C#代码是:
Insert(new SomeGroup
{
// I'm not providing Id here, cause it will be auto-generated
SomeGroupId = otherGroup.Id,
Title = otherGroup.Title
});
Here也是对此的一些解释。
答案 7 :(得分:0)
在我的情况下,EntityFramework在Context.cs
类内生成了以下代码:
modelBuilder.Entity<MODEL_OF_TABLE>(entity =>
{
entity.Property(e => e.Id).ValueGeneratedNever(); // <= this line must remove
...
}
删除此行后,问题解决了。
答案 8 :(得分:0)
也遇到了这个问题。对我来说,我的开发数据库表由于某种原因没有带来密钥,所以 EF 没有将我的 ID 定义为密钥。
遇到此问题的任何人请注意:确保您尝试将新记录插入到具有 ID 字段的表实际上是在您的 Context 类中定义的。
modelBuilder.Entity<CustomerEmail>(entity =>
{
entity.HasKey(e => e.Id)
.HasName("PK_tblCustomerEmail");
entity.Property(e => e.Customer).IsUnicode(false);
entity.Property(e => e.Email).IsUnicode(false);
});
答案 9 :(得分:-1)
如果您首先使用数据库方法,然后先从edmx图中删除相应的实体,然后从数据库中更新模型,这肯定会解决您的问题