我有两个实体类,它们具有多对多关系类,未被建模为弱实体:
public class Foo
{
public Guid Id { get; private set; }
public ICollection<Baz> Bazs { get; private set; }
}
public class Bar
{
public long Id { get; private set; }
}
public class Baz
{
public Guid Id { get; private set; }
public Foo Foo { get; private set; }
public Bar Bar { get; private set; }
// other things
}
我的EntityTypeConfigurations
就像这样构建:
public class FooConfiguration : EntityTypeConfiguration<Foo>
{
HasMany(f => f.Bazs).WithRequired(b => b.Foo).Map(c => c.ToTable("FooBars"));
}
public class BarConfiguration : EntityTypeConfiguration<Bar>
{
//no navigation mapping
}
public class BazConfiguration : EntityTypeConfiguration<Baz>
{
HasRequired(b => b.Foo).WithMany(f => f.Bazs);
HasRequired(b => b.Bar).WithMany();
}
我遇到的问题是,当我加载Foo
时,Bar
关系的Baz
方面无法加载。我已经更改了Baz
上的属性以获得支持字段并在setter上设置断点,并且Foo
的setter被调用,但Bar
的setter却没有。我还尝试在Bar
虚拟上创建Baz
属性,看看是否出于某种原因需要急切加载的情况。这种用法的一个例子:
var foo = Set<Foo>.Single(f => f.Id == Id);
var barIds = foo.Bazs.Select(b => b.Bar.Id).ToList();
// the projection lambda throws because b.Bar is null
但是,如果我明确加载Bar
,他们做会填充:
var bars = Set<Bar>().ToList();
var foo = Set<Foo>().Single(f => f.Id == Id);
var barIds = foo.Bazs.Select(b => b.Bar.Id).ToList();
// barIds now contains the correct IDs for the associated Bars
我的问题是:
Bar
之前加载Foo
的解决方法是填充实体的唯一方法吗?其他信息
我已尝试直接在ICollection<Bar>
上使用Foo
,该Foo
用于加载Bar
- &gt; Baz
关系,但因为SaveChanges()
是不是弱实体,此设置在{{1}}上失败。
我尝试过两种方式映射集合,但是that's apparently not possible either。
答案 0 :(得分:2)
在你的例子中“工作”EF只是填充属性,因为它在它的本地缓存中有它们,但是这不是你需要的方法。
您需要在查询中明确包含Bazs.Bar
,如下所示,它们会急切加载它们。
var foo = Set<Foo>().Include("Bazs.Bar").Single(f => f.Id == Id);
或者,如果您将导航属性声明为virtual
,那么这将启用延迟加载。
public class Foo
{
public Guid Id { get; private set; }
public virtual ICollection<Baz> Bazs { get; private set; }
}
public class Baz
{
public Guid Id { get; private set; }
public virtual Foo Foo { get; private set; }
public virtual Bar Bar { get; private set; }
// other things
}
答案 1 :(得分:0)
值得注意的一件事(虽然不必修正 OP,但是因为代码示例是Foo-Bared,所以可能会过于简化-无论如何,已经有4年了,所以我确定OP不再关心了。
EF要求实体类至少具有受保护的无参数构造函数。 如果您的参数构造函数是私有的,则将加载该实体,但是导航属性的延迟加载将不起作用-不管它是否是虚拟的。
必须显式加载导航属性(例如,使用Include
)。
嘘:
public class Foo
{
//private constructor won't lazy-load navigation properties (virtual or not).
//change to protected
private Foo(){}
public Foo(string name)
{
this.Name = name;
}
public string Name {get;set;}
public Guid Id { get; private set; }
public virtual ICollection<Baz> Bazs { get; private set; }
}