【问题标题】:Entity Framework Code First custom join实体框架代码优先自定义连接
【发布时间】:2011-03-19 18:16:08
【问题描述】:

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

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

我认为下一个最好的办法就是用 SQL 编写一个视图来进行自定义连接?

谢谢。

【问题讨论】:

    标签: .net entity-framework ef-code-first entity-framework-4.1


    【解决方案1】:

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

    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 触发器,否则查看也不可行。

    不用映射也可以做到:

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

    你也可以不带属性定义它,但你需要在OnModelCreating上使用Ignore

    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();
    

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

    【讨论】:

    • 谢谢,那里有一些有趣的东西。我应该提到该表已经在数据库中,所以我不担心代码生成方面的事情,但我从你的帖子中学到了一些新东西!我可能仍然使用视图,因为它仅用于搜索结果,我不确定我是否喜欢多次往返的想法。
    猜你喜欢
    • 2015-04-09
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多