2010-03-02 10 views
2

Я новичок в EF 4.0, поэтому, возможно, это простой вопрос. У меня есть VS2010 RC и последний EF CTP. Я пытаюсь реализовать первый пример кода «Foreign Keys» в блоге Design Team Design, http://blogs.msdn.com/efdesign/archive/2009/10/12/code-only-further-enhancements.aspx.Использование Entity Framework 4.0 с Code-First и POCO: как получить родительский объект со всеми его детьми?

public class Customer 
{ 
    public int Id { get; set; 
    public string CustomerDescription { get; set; 
    public IList<PurchaseOrder> PurchaseOrders { get; set; } 
} 

public class PurchaseOrder 
{ 
    public int Id { get; set; } 
    public int CustomerId { get; set; } 
    public Customer Customer { get; set; } 
    public DateTime DateReceived { get; set; } 
} 

public class MyContext : ObjectContext 
{ 
    public RepositoryContext(EntityConnection connection) : base(connection){} 
    public IObjectSet<Customer> Customers { get {return base.CreateObjectSet<Customer>();} } 
} 

Я использую ContextBuilder настроить MyContext:

{ 
    var builder = new ContextBuilder<MyContext>(); 

    var customerConfig = _builder.Entity<Customer>(); 
    customerConfig.Property(c => c.Id).IsIdentity(); 

    var poConfig = _builder.Entity<PurchaseOrder>(); 
    poConfig.Property(po => po.Id).IsIdentity(); 

    poConfig.Relationship(po => po.Customer) 
     .FromProperty(c => c.PurchaseOrders) 
     .HasConstraint((po, c) => po.CustomerId == c.Id); 

    ... 
} 

Это работает правильно, когда я добавляю новых клиентов, но не тогда, когда я пытаюсь получить существующих клиентов. Этот код успешно сохраняет нового Заказчика и всех его дочерних Покупателей:

using (var context = builder.Create(connection)) 
{ 
    context.Customers.AddObject(customer); 
    context.SaveChanges(); 
} 

Но этот код только извлекает объекты Заказчика; списки PurchaseOrders всегда пусты.

using (var context = _builder.Create(_conn)) 
    { 
     var customers = context.Customers.ToList(); 
    } 

Что еще мне нужно сделать, чтобы ContextBuilder сделать MyContext всегда извлекать все PurchaseOrders с каждым клиентом?

ответ

2

Ну, решение оказалось простым, как я подозревал. Я назвал метод context.LoadProperty() для каждого отдельного клиента:

using (var context = _builder.Create(_conn)) 
{ 
    var customers = context.Customers.ToList(); 
    foreach (var customer in customers) 
    { 
     context.LoadProperty<Customer>(customer, c => c.PurchaseOrders); 
    } 
    return customers; 
} 
+4

Я бы с осторожностью относился к этому подходу, поскольку вы делаете n круглых поездок в базу данных, по одному для каждого клиента. А что, если у вас было несколько детских коллекций на Клиенте? Лучшим подходом было бы использование Include (см. Ниже), которое будет извлекать все это в одном запросе в БД. –

1

Я работаю с выпущенной версией 4.0/VS 2010/EF и я не могу показаться, чтобы найти пространство имен, где ContextBuilder является сохраняются. В примерах CTP я видел, что он находится в «Microsoft.Data.Objects», но я не могу найти эту ссылку. У меня не было проблем с созданием примера Model-First, но я застрял в примере Code-First, с которым я работаю ... любая помощь очень ценится!

+5

Вам нужно скачать его отдельно: http://stackoverflow.com/questions/2739808/entity-framework-contextbuilder-namespace – Chris

3

Вы также можете использовать:

var customers = context.Customers.Include("PurchaseOrders").ToList(); 

Или включите LazyLoading в ContextOptions:

context.ContextOptions.LazyLoadingEnabled = true; 

Просто будьте осторожны с отложенной загрузки, если вы сериализации объектов или вы можете в конечном итоге запрашивая цельные база данных.