【问题标题】:ArgumentException is thrown when working with ChangeTracker in overriden SaveChanges method在覆盖的 SaveChanges 方法中使用 ChangeTracker 时引发 ArgumentException
【发布时间】:2012-11-03 21:22:00
【问题描述】:

我重写了 SaveChanges 方法来审核 EntityFramework 中的更改。在我尝试更新关联对象之前,它工作正常。当我尝试更新关联对象时,我得到 ArgumentException。我发现从 ChangeTracker 读取实体后会引发异常。如果我在覆盖的 SaveChanges 方法中对 ChangeTracker 不执行任何操作,则对象将成功更新。我使用 EntityFramework 5.0。

你不知道这是一个错误还是我做错了什么?

抛出异常:

System.ArgumentException 被捕获 HResult=-2147024809
Message=定义 EntityKey 的键值对不能为 null 或 空的。参数名称:记录 Source=System.Data.Entity
参数名称=记录堆栈跟踪: 在 System.Data.EntityKey.GetKeyValues(EntitySet entitySet, IExtendedDataRecord 记录, String[]& keyNames, Object& 单例键值、对象 [] 和复合键值) 在 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(Func2 谓词) 在 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() 在 c:\Projects\EF22\EFTest2Solution\EFTest2\Context.cs:line 37 中的 EFTest2.BlogContext.SaveChanges() 在 EFTest2.Program.Main(String[] args) 在 c:\Projects\EF22\EFTest2Solution\EFTest2\Program.cs:line 42

我的代码是这样的: 程序.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;
    }
  }

【问题讨论】:

    标签: c# entity-framework entity-framework-5 change-tracking


    【解决方案1】:

    来自 msdn 的反应...这是一个错误。要解决此问题,必须使用不可为空的主键。

    在 EF codeplex 站点报告了错误:Exception thrown when calling detect changes twice with nullable primary keys

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-10
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      相关资源
      最近更新 更多