Reputation: 127
I am having some problems with the Ef 4.1 code first implementation.
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; }
}
When I put a wcf service on top of this, it only returns an empty collection of Bars. If I turn on the ProxyCreationEnabled, the collection will be filled, but then I will get wcf exceptions and closed connections because of the EF proxy creation.
Any suggestions?
Upvotes: 3
Views: 2056
Reputation: 364349
You must use eager loading if you want to load Bars as well. EF never loads related objects by itself. You must always ask EF for related objects either by eager loading or lazy loading. If you turn on proxy creation EF will try to load Bars collection by lazy loading during data serialization (first time the collection is accessed) but you will either get exception because of closed context or because of cycle in serialized data (Bar.Foo
and Foo.Bars
create cycle).
To use eager loading you must add Include
method to your query:
var data = context.Foos.Include(f => f.Bars).ToList();
To avoid cycles you must either remove Foo
in Bar
or mark Foo and Bar with DataContract
with IsReference=true
and DataMember
attributes:
[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;}
}
Or you will have to mark Foo
property in Bar
as not serialized to break a cycle:
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;}
}
Upvotes: 6