Entity framework 4 复杂模型到多个表(获取和插入)

Entity framework 4 复杂模型到多个表(获取和插入),entity-framework-4,linq-to-entities,ef-code-first,entity-framework-4.1,Entity Framework 4,Linq To Entities,Ef Code First,Entity Framework 4.1,我使用的是代码优先和实体框架 我有一个注册实体,该实体具有其他型号的多个属性: public class Registration { public int ID { get; set; } public int OrganizationID { get; set; } public Address RegAddress { get; set; } public ContactInformation RegContactIn

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

我有一个
注册
实体,该实体具有其他型号的多个属性:

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; }        
    }
通过此设置,我确实有了
地址
联系人信息
型号。当我保存注册时,它会像我期望的那样工作。包含3个表的数据库(
注册
地址
联系人信息
)。与
注册
具有FK到其他两个

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

    DBConnections dbConnections = new DBConnections();

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

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

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

延迟加载 延迟加载将为您提供相关实体的自动加载,但它将生成对数据库的附加查询。首次访问属性时,将加载相关实体或相关集合。要使用延迟加载,您必须将实体中的所有导航属性标记为
虚拟
(此外,延迟加载或代理创建不得禁用-默认情况下允许)。只有当用于加载主实体的上下文仍然处于活动状态时,延迟加载才有效。要允许延迟加载,必须修改实体:

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
方法定义。您可以将查找重写为:

var registrations = from r in dbConnections.PlayerRegistrations
                                           .Include(p => p.Address)
                                           .Include(p => p.RegContactInformation)
                    where r.OrganizationID == orgID
                    select r;
请注意,在从数据库返回的数据的数量和形式上,可能会出现负载过大的情况

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

context.Entry(registration).Reference(c => c.Address).Load();
此方法对于加载相关集合更有用

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