存在列表导航属性时,AutoDetectChanges不起作用

时间:2019-06-22 13:20:55

标签: c# entity-framework-6 navigation-properties

我遇到了一个错误,即在某些依赖EF6的代码中,未检测到更改(尽管这些更改已保存到数据存储中)。

使用List<Child>导航属性时,如果更改父对象中的属性,则不会检测到更改。 EntityState保持不变。

示例控制台应用程序(带有NuGet EntityFramework 6.2的.NET Framework 4.7.2)代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.ComponentModel.DataAnnotations.Schema;

namespace EFStateTest
{
    public class Tests
    {
        public static void Main()
        {
            var context = new StandaloneContext();


            /* First time run, generate some test data to work with */
            if (!context.Set<ParentTable>().Any())
            {
                ParentTable p = new ParentTable()
                {
                    Data = "Foo",
                    Children = new List<ChildTable>()
                    {
                        new ChildTable()
                        {
                            ManyData = "Bar",
                        },
                    },
                };

                context.Set<ParentTable>().Add(p);
            }
            /* nth run, do the test */
            else
            {
                var p = context.Set<ParentTable>().FirstOrDefault();        // Get our test record

                p.Data = DateTime.Now.Ticks.ToString();     // Change some data

                try
                {
                    // Get the state
                    object d = p.GetType().GetField("_entityWrapper").GetValue(p);
                    System.Data.Entity.Core.Objects.ObjectStateEntry ose = d.GetType().GetProperty("ObjectStateEntry").GetValue(d) as System.Data.Entity.Core.Objects.ObjectStateEntry;
                    Console.WriteLine(ose.State);
                }
                catch
                {
                    Console.WriteLine("Not a proxy class");
                }
            }

            context.SaveChanges();
            Console.WriteLine("DONE");
            Console.ReadLine();
        }
    }

    // Context
    public class StandaloneContext : DbContext
    {
        public StandaloneContext() : base("Server=(local);Database=EFTest;Integrated Security=SSPI")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new ParentTableSchema());
            modelBuilder.Configurations.Add(new ChildTableSchema());

            base.OnModelCreating(modelBuilder);
        }
    }

    public class ParentTable
    {
        public virtual int Id { get; set; }
        public virtual string Data { get; set; }

        public virtual List<ChildTable> Children { get; set; }
    }

    public class ChildTable
    {
        public virtual int Id { get; set; }
        public virtual int ParentId { get; set; }
        public virtual string ManyData { get; set; }

        public virtual ParentTable Parent { get; set; }
    }

    public class ParentTableSchema : EntityTypeConfiguration<ParentTable>
    {
        public ParentTableSchema()
        {
            HasKey(m => m.Id)
                .Property(m => m.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

            HasMany(m => m.Children)
                .WithRequired(c => c.Parent)
                .HasForeignKey(c => c.ParentId);
        }
    }

    public class ChildTableSchema : EntityTypeConfiguration<ChildTable>
    {
        public ChildTableSchema()
        {
            HasKey(m => m.Id)
                .Property(m => m.Id)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        }
    }
}

运行一次以在本地计算机上生成数据库,然后再次显示该错误。更改父对象(p.Data = DateTime.Now.Ticks.ToString();)的属性不会更改实体的跟踪状态,我使用反射将其放置在此处,但这与在上下文中使用ChangeTracker时相同。

现在,如果您删除List<ChildTable> Children的导航集合,那么问题就消失了(但是我有点想要导航属性),并且更改跟踪器正确地更改为Modified。

我已经有一个修复程序,但是没有回答为什么。将导航属性更改为ICollection<ChildTable>而不是List,IList等,它也可以工作。

到目前为止,我在EF上阅读的文档都说导航属性需要实现ICollection-List可以实现。那么,这里有什么呢?我是在弄错其他东西,还是完全错过了东西?

0 个答案:

没有答案