1

我有一个客户表和一个地址表。客户可以有多个地址,但他们也有一个标记为他们的主要地址(如果他们有任何地址)。

在代码中是否有某种方式,我可以在 Customer POCO 中放置一个名为“PrimaryAddress”的字段,并使用诸如 Customers.Include(customer => customer.PrimaryAddress) 之类的内容来获取与客户并且设置了主要位?

我认为下一个最好的事情就是在 SQL 中编写一个自定义连接的视图?

谢谢。

4

1 回答 1

3

我不认为这是直接可能的。如果您映射某些内容,它将最终成为关系或列。因此,如果您希望您的客户看起来像:

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_IDAddresses 表中或 M:N(联结表)关系。

这不是很好,因为还应该有一些PrimaryAddress_ID必须来自与客户相关的地址的约束。这种约束可能需要通过触发器进行检查。

除非您正在构建只读应用程序或者您准备好定义 INSTEAD OF 触发器,否则 View 也不可行。

你可以在没有映射的情况下做到这一点:

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
    }
}

您也可以在没有属性的情况下定义它,但您需要使用Ignoreon 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();

这将只加载主地址,但您必须先加载客户,因此您必须循环访问数据库。

于 2011-03-19T22:28:58.647 回答