EF,Code First,WCF =>空集合问题

Haa*_*onL 3 c# wcf ef-code-first entity-framework-4.1

我在使用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; }
}
Run Code Online (Sandbox Code Playgroud)

当我在其上放置一个wcf服务时,它只返回一个空的Bars集合.如果我打开ProxyCreationEnabled,集合将被填充,但由于EF代理创建,我将获得wcf异常和关闭连接.

有什么建议?

Lad*_*nka 6

如果您还要加载条形,则必须使用预先加载.EF从不自行加载相关对象.您必须始终通过急切加载或延迟加载向EF询问相关对象.如果启用代理创建,EF将尝试在数据序列化期间(第一次访问集合时)通过延迟加载来加载Bars集合,但是由于关闭上下文或者因为序列化数据中的循环(Bar.Foo以及Foo.Bars创建周期),您将获得异常.

要使用预先加载,您必须Include在查询中添加方法:

var data = context.Foos.Include(f => f.Bars).ToList();
Run Code Online (Sandbox Code Playgroud)

为了避免循环您必须删除FooBar或标记符,并与酒吧DataContractIsReference=trueDataMember属性:

[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;}
}
Run Code Online (Sandbox Code Playgroud)

或者您必须将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;}
}
Run Code Online (Sandbox Code Playgroud)