我有一个Customers表和一个Addresses表。客户可以拥有多个地址,但也有一个地址被标记为主要地址(如果他们有任何地址)。
在代码中是否存在某种方式,我可以将一个字段放在名为“PrimaryAddress”的Customer POCO中,并使用Customers.Include(customer => customer.PrimaryAddress)之类的东西来获取地址是否与客户有关并且设置了主要位?
我认为下一个最好的事情就是在SQL中编写一个自定义连接的视图?
感谢。
答案 0 :(得分: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_ID
表中的Addresse
或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();
这将仅加载主地址,但您必须首先加载客户,因此您必须将数据汇总到数据库。