Код Entity Framework Первое пользовательское соединение - PullRequest
1 голос
/ 19 марта 2011

У меня есть таблица клиентов и таблица адресов.У клиентов может быть много адресов, но у них также есть один, который помечен как их основной адрес (если у них есть какие-либо адреса).

Есть ли какой-нибудь способ в коде сначала, где я могу поместить поле в КлиентаPOCO называется "PrimaryAddress" и использует что-то вроде Customers.Include (customer => customer.PrimaryAddress), чтобы просто подобрать адрес, который связан с клиентом И установлен ли первичный бит?

Я предполагаю следующееЛучше всего было бы просто написать представление в SQL, в которое входит пользовательское соединение?

Спасибо.

1 Ответ

3 голосов
/ 20 марта 2011

Я не думаю, что это напрямую возможно.Если вы отобразите что-либо, оно будет либо в виде отношения, либо в виде столбца.Поэтому, если вы ожидаете, что ваш клиент будет выглядеть следующим образом:

public class Customer
{
    ...
    public Address PrimaryAddress { get; set; }
    public ICollection<Address> Addresses { get; set; }
}

Он будет выглядеть как таблица:

CREATE TABLE dbo.Customers
(
    ...
    PrimaryAddress_ID INT NULL
)

В зависимости от определения Address у вас будет либо Addressesотображается как 1: N (Customer_ID в таблице Addresse s или в соотношении M: N (соединительная таблица).

Это не очень хорошо, поскольку также должно быть какое-то ограничение, что PrimaryAddress_ID должно быть изадреса, связанные с клиентом. Такое ограничение, вероятно, нужно будет проверить с помощью триггера.

Просмотр также не подходит, если вы не создаете приложение только для чтения или не готовы определить триггеры INSTEAD OF.

Вы можете сделать это без сопоставления:

public class Customer
{
    ...
    public ICollection<Address> Addresses { get; set; }

    [NotMapped]
    public Address PrimaryAddress
    {
        get
        {
            return Addresses.Single(a => a.IsPrimary);
        }
        // If you need set you can implement it in similar way
    }
}

Вы также можете определить это без атрибута, но вам нужно использовать Ignore для OnModelCreating:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>()
        .Ignore(c => c.PrimaryAddress);
}

Недостаток подхода заключается в том, что он всегда будет загружать все адреса.

Если вы знаете, что вам не понадобится другой, кроме основного адреса, который вы можете использовать:

context.Entry<Customer(customer)
    .Collection(c => c.Addresses)
    .Query()
    .Where(a => a.IsPrimary)
    .Load();

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

...