我重写了SaveChanges方法来审核EntityFramework中的更改。这工作正常,直到我尝试更新关联的对象。当我尝试更新关联对象时,我得到ArgumentException。我发现从ChangeTracker读取实体后抛出了异常。如果我在重写SaveChanges方法中对ChangeTracker不做任何操作,则会成功更新对象。我使用EntityFramework 5.0。
如果这是一个错误或我做错了,请你知道吗?
抛出异常:
发现了System.ArgumentException HResult = -2147024809
Message =定义EntityKey的键值对不能为null或 空。参数名称:record Source = System.Data.Entity
ParamName =记录StackTrace: 在System.Data.EntityKey.GetKeyValues(EntitySet entitySet,IExtendedDataRecord record,String []& keyNames,Object& singletonKeyValue,Object []& compositeKeyValues) 在System.Data.EntityKey..ctor(EntitySet entitySet,IExtendedDataRecord记录) 在System.Data.Objects.ObjectStateManager.PerformDelete(IList1 entries) at System.Data.Objects.ObjectStateManager.DetectChanges() at System.Data.Objects.ObjectContext.DetectChanges() at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force) at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func
2 谓语) 在System.Data.Entity.Internal.InternalContext.GetStateEntries() 在System.Data.Entity.Infrastructure.DbChangeTracker.Entries() 在System.Data.Entity.DbContext.GetValidationErrors() 在System.Data.Entity.Internal.InternalContext.SaveChanges() 在System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 在System.Data.Entity.DbContext.SaveChanges() 在EFTest2.BlogContext.SaveChanges()在c:\ Projects \ EF22 \ EFTest2Solution \ EFTest2 \ Context.cs:第37行 at EFTest2.Program.Main(String [] args)在c:\ Projects \ EF22 \ EFTest2Solution \ EFTest2 \ Program.cs:第42行
我的代码看起来像这样: Program.cs的
class Program
{
static void Main(string[] args)
{
var configuration = new Configuration();
configuration.TargetDatabase = new DbConnectionInfo("Data Source=server;Initial Catalog=EntityFramework;Integrated Security=True", "System.Data.SqlClient");
var migrator = new DbMigrator(configuration);
var scriptor = new MigratorScriptingDecorator(migrator);
var script = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: null);
Console.WriteLine(script);
var pending = migrator.GetPendingMigrations();
migrator.Update();
using (var ctx = new BlogContext())
{
Post post = new Post { Content = "Content", SpecialBlog = new Blog() { Title = "SpecialBlog" } };
ctx.Posts.Add(post);
ctx.SaveChanges();
post.SpecialBlog = new Blog() { Title = "Update SpecialBlog" };
ctx.SaveChanges(); // ArgumentException is thrown when using ChangeTracker
}
}
}
模型
public class Blog
{
public int? BlogId { get; set; }
public string Title { get; set; }
public ICollection<Post> Posts { get; set; }
}
public partial class BlogMap : EntityTypeConfiguration<Blog>
{
public BlogMap()
: base()
{
HasKey(c => c.BlogId);
Property(c => c.Title).IsRequired().HasMaxLength(40);
ToTable("Blog");
}
}
public class Post
{
public int? PostId { get; set; }
public string Content { get; set; }
public int? BlogId { get; set; }
public Blog Blog { get; set; }
public int? SpecialBlogId { get; set; }
public Blog SpecialBlog { get; set; }
}
public partial class PostMap : EntityTypeConfiguration<Post>
{
public PostMap()
: base()
{
HasKey(c => c.PostId);
Property(c => c.Content);
HasOptional(m => m.Blog)
.WithMany(t => t.Posts)
.HasForeignKey(m => m.BlogId)
.WillCascadeOnDelete(false);
HasOptional(m => m.SpecialBlog)
.WithMany()
.HasForeignKey(m => m.SpecialBlogId)
.WillCascadeOnDelete(false);
ToTable("Post");
}
}
上下文:
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new DropCreateDatabaseAlways<BlogContext>());
modelBuilder.Configurations.Add(new PostMap());
modelBuilder.Configurations.Add(new BlogMap());
}
public override int SaveChanges()
{
var entries = ChangeTracker.Entries(); // causes ArgumentNullException after calling base.SaveChanges();
return base.SaveChanges();
}
}
配置
public class Configuration : DbMigrationsConfiguration<BlogContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
答案 0 :(得分:0)
来自msdn的反应......这是一个错误。要修复它,必须使用不可为空的主键。
在EF codeplex网站上报告了错误:Exception thrown when calling detect changes twice with nullable primary keys