【问题标题】:Complex model to multiple tables (get and insert)多个表的复杂模型(获取和插入)
【发布时间】:2011-05-16 02:14:25
【问题描述】:

我使用的是代码优先和实体框架。

我有一个Registration 实体,它具有其他模型的几个属性:

public class Registration
    {
        public int ID { get; set; }
        public int OrganizationID { get; set; }
        public Address RegAddress { get; set; }
        public ContactInformation RegContactInformation { get; set; }
        public string Signature{ get; set; }        
    }

通过此设置,我确实有一个 AddressContactInformation 模型。当我保存注册时,它会按我的预期工作。具有 3 个表(RegistrationAddressContactInformation)的数据库。 Registration 对其他两个有 FK。

但是,当我尝试使用 EF 从我的数据库中获取注册信息时:

    DBConnections dbConnections = new DBConnections();

    var registrations = from r in dbConnections.PlayerRegistrations
                        where r.OrganizationID == orgID
                        select r;

Registration.Address 和Registration.ContactInformation 为空。我怎样才能做到这一点?

【问题讨论】:

    标签: entity-framework-4 linq-to-entities ef-code-first entity-framework-4.1


    【解决方案1】:

    这是正确的行为,因为 EF 从不加载相关实体本身。要加载相关属性,您必须使用以下方法之一:

    延迟加载

    延迟加载将为您提供相关实体的自动加载,但它会生成额外的数据库查询。当您第一次访问该属性时,将加载相关实体或相关集合。要使用延迟加载,您必须将实体中的所有导航属性标记为virtual(也不能禁用延迟加载或代理创建 - 默认情况下允许)。仅当用于加载主实体的上下文仍然存在时,延迟加载才有效。要允许延迟加载,您必须修改您的实体:

    public class Registration
    {
        public int ID { get; set; }
        public int OrganizationID { get; set; }
        public virtual Address RegAddress { get; set; }
        public virtual ContactInformation RegContactInformation { get; set; }
        public string Signature{ get; set; }        
    }
    

    渴望加载

    预加载将定义必须与主实体一起加载的关系。急切加载由Include 方法定义。您可以将 Find 重写为:

    var registrations = from r in dbConnections.PlayerRegistrations
                                               .Include(p => p.Address)
                                               .Include(p => p.RegContactInformation)
                        where r.OrganizationID == orgID
                        select r;
    

    请注意,在从数据库返回的数据量和形式上急切加载 has big impact

    显式加载

    显式加载将允许您明确表示应该加载某些关系。您甚至可以定义一些条件来加载相关实体,这是其他两种方法无法实现的。您必须首先加载主实体,然后在处理上下文之前,您可以执行以下操作:

    context.Entry(registration).Reference(c => c.Address).Load();
    

    这个方法对于加载相关集合比较有用。

    自定义加载

    自定义加载意味着您​​将对每个关系使用单独的查询。这看起来像是您不想做的事情,但是对于传输结果集的一些性能优化,这可能非常有用(这解决了在急切加载部分中链接的问题)。此方法的要点是,如果您对关系使用单独的查询,EF 仍将正确填充导航属性。此方法仅适用于加载相关集合,并且仅在关闭延迟加载时才有效。

    【讨论】:

      猜你喜欢
      • 2016-09-24
      • 2016-01-22
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-21
      • 2021-02-05
      相关资源
      最近更新 更多