播种 EF 4.1 时代理的第一个导航属性为空

Posted

技术标签:

【中文标题】播种 EF 4.1 时代理的第一个导航属性为空【英文标题】:Proxy's First Navigation Property is null when Seeding EF 4.1 【发布时间】:2011-07-21 22:16:43 【问题描述】:

Initializer.Seed() 使用DbContext.DbSet.Find() 为新代理设置导航属性时,它会正确地将FK 分配给代理,但是当我中断@ 时,first 导航属性始终为空987654323@ 并检查代理。有谁知道为什么会这样?

(抱歉,我无法发布本地窗口的屏幕截图。)

型号

public class Thing : Base 
    public virtual Nullable<int> Option1ID  get; set; 
    public virtual Option1 Option1  get; set; 
    public virtual Nullable<int> Option2ID  get; set; 
    public virtual Option2 Option2  get; set; 
    public virtual Nullable<int> Option3ID  get; set; 
    public virtual Option3 Option3  get; set; 

public class Option1 : Base 
    public virtual ICollection<Thing> Things  get; set; 

public class Option2 : Base 
    public virtual ICollection<Thing> Things  get; set; 

public class Option3 : Base 
    public virtual ICollection<Thing> Things  get; set; 

public class Base 
    public virtual int Id  get; set; 
    public virtual string Name  get; set; 

数据库上下文

public class Context : DbContext 
    public DbSet<Thing> Things  get; set; 
    public DbSet<Option1> Option1s  get; set; 
    public DbSet<Option2> Option2s  get; set; 
    public DbSet<Option3> Option3s  get; set; 

    public ObjectContext ObjectContext 
        get  return ((IObjectContextAdapter)this).ObjectContext; 
    

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
        base.OnModelCreating(modelBuilder);
    

种子()

var option1s = new List<Option1> 
    new Option1Name="Red",
    new Option1Name="Green";
    option1s.ForEach(x => db.Option1s.Add(x));
    db.SaveChanges();
var option2s = new List<Option2> 
    new Option2Name = "Tall",
    new Option2Name = "Short";
    option2s.ForEach(x => db.Option2s.Add(x));
    db.SaveChanges();
var option3s = new List<Option3> 
    new Option3Name = "Male",
    new Option3Name = "Female";
    option3s.ForEach(x => db.Option3s.Add(x));
    db.SaveChanges();

var thing = db.Things.Create();
    thing.Option1 = db.Option1s.Find(1); //the first thing.XXXX shows null no matter what order
    thing.Option2 = db.Option2s.Find(1); //but the FK's work for all three of them
    thing.Option3 = db.Option3s.Find(1);
db.Things.Add(thing);
db.SaveChanges();

【问题讨论】:

我认为这是一个错误。我在下面添加了一个编辑。 【参考方案1】:

哇。我不知道你在那里做了什么,但你让对象状态跟踪器非常生气。

编辑:

我认为这是调试器中的某种错误以及它与动态代理一起工作的方式。我这样说是因为你可以这样做 Console.WriteLine(thing.Option1.Id); 它会给你正确的 id。如果您通过说var thing = new Thing(); 摆脱动态代理,调试器问题就会消失。

这是执行您想做的事情的更标准方法。

    var option1s = new List<Option1> 
            new Option1Name="Red",
            new Option1Name="Green";
    option1s.ForEach(x => db.Option1s.Add(x));

    var option2s = new List<Option2> 
            new Option2Name = "Tall",
            new Option2Name = "Short";
    option2s.ForEach(x => db.Option2s.Add(x));

    var option3s = new List<Option3> 
            new Option3Name = "Male",
            new Option3Name = "Female";
    option3s.ForEach(x => db.Option3s.Add(x));

    var thing = db.Things.Create();
    thing.Option1 = option1s[0];
    thing.Option2 = option2s[0];
    thing.Option3 = option3s[0];

    db.Things.Add(thing);
    db.SaveChanges();

【讨论】:

感谢您的调查。我在致电Create() 后立即致电db.Things.Add(thing),问题就消失了。尽管如此,尽管您指出调试混乱,但它一直在工作。当_changeTracker 为空时,它似乎对第一个属性做了奇怪的事情。我还在上下文中添加了一个方法,该方法既可以创建又可以添加新代理,这样我以后就不会忘记设置 EntityState。你怎么看?一开始没有添加实体是我的错吗?还是应该按照我的方式处理新创建的实体?

以上是关于播种 EF 4.1 时代理的第一个导航属性为空的主要内容,如果未能解决你的问题,请参考以下文章

EF 代码优先 - 删除然后创建数据库后播种

EF6虚拟导航属性是否导致SQL查询?

Asp.net 核心导航属性始终为空

EF 4.1 Code First 添加到外键集合

无法加载EF Core中的 "一对多 "导航属性。

EF:“包含”导航属性,当使用“选择”投影创建包装对象时