EF, Code First, WCF => пустая проблема с коллекцией - PullRequest
3 голосов
/ 03 мая 2011

У меня есть некоторые проблемы с первой реализацией кода 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, коллекция будет заполнена, но тогда я получу исключения wcf и закрытые соединения из-за создания прокси EF.

Есть предложения?

1 Ответ

6 голосов
/ 03 мая 2011

Вы должны использовать энергичную загрузку, если вы также хотите загружать бары.EF никогда не загружает связанные объекты самостоятельно.Вы всегда должны спрашивать EF о связанных объектах, либо загружая их, либо ленивая загрузка.Если вы включите создание прокси, EF попытается загрузить коллекцию Bars путем отложенной загрузки во время сериализации данных (при первом обращении к коллекции), но вы получите исключение из-за закрытого контекста или из-за цикла в сериализованных данных (Bar.Foo и *).1002 * создать цикл).

Чтобы использовать готовую загрузку, вы должны добавить к вашему запросу метод Include:

var data = context.Foos.Include(f => f.Bars).ToList();

Чтобы избежать циклов, вы должны либо удалить Foo в Bar, либо пометить Foo and Bar какDataContract с атрибутами IsReference=true и DataMember:

[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;}
}
...