我在使用Ef 4.1代码时遇到了一些问题。
public class Foo()
{
public Foo()
{
Id = Guid.NewGuid();
Bars = new Collection<Bar>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public virtual ICollection Bars { get; set; }
}
public class Bar()
{
public Bar()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public string Name { get; set; }
public virtual Foo Foo { get; set;}
}
public class MyContext : DbContext
{
public MyContext()
{
Configuration.ProxyCreationEnabled = false;
}
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
}
当我在其上放置一个wcf服务时,它只返回一个空的Bars集合。如果我打开ProxyCreationEnabled,集合将被填充,但由于EF代理创建,我将获得wcf异常和关闭连接。
有什么建议吗?
答案 0 :(得分:6)
如果您还要加载条形图,则必须使用预先加载。 EF从不自行加载相关对象。您必须始终通过急切加载或延迟加载向EF询问相关对象。如果启用代理创建,EF将尝试在数据序列化期间(第一次访问集合时)通过延迟加载来加载Bars集合,但是由于关闭上下文或者因为序列化数据中的循环而导致异常(Bar.Foo
和Foo.Bars
创建周期)。
要使用预先加载,您必须在查询中添加Include
方法:
var data = context.Foos.Include(f => f.Bars).ToList();
要避免周期,您必须删除Foo
中的Bar
或使用DataContract
和IsReference=true
属性DataMember
标记Foo和栏:
[DataContract(IsReference=true)]
public class Foo()
{
public Foo()
{
Id = Guid.NewGuid();
Bars = new Collection<Bar>();
}
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public virtual ICollection Bars { get; set; }
}
[DataContract(IsReference=true)]
public class Bar()
{
public Bar()
{
Id = Guid.NewGuid();
}
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public virtual Foo Foo { get; set;}
}
或者您必须将Foo
中的Bar
属性标记为未序列化以打破周期:
public class Bar()
{
public Bar()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public string Name { get; set; }
[IgnoreDataMember]
public virtual Foo Foo { get; set;}
}