繁体   English   中英

我是否可以使用Entity Splitting在实体框架6中延迟加载实体的一部分?

[英]Can I lazy load part of an entity in Entity Framework 6 with Entity Splitting?

我对Entity Framework很陌生,虽然它比NHibernate有许多优点,但我发现它不支持延迟加载属性我很失望。

上这堂课:

public class Product
{ 
    public virtual Guid Id {get;set;}
    public virtual string Name {get;set;}
    public virtual string Details {get;set;}
}

我的计划是使用Entity Splitting将它映射到两个表:

CREATE TABLE [dbo].[Product](
[Id] [uniqueidentifier] NOT NULL PRIMARY KEY,
[Name] [nvarchar](50) NULL
) 

CREATE TABLE [dbo].[ProductDetails](
[Id] [uniqueidentifier] NOT NULL PRIMARY KEY,
[Details] [nvarchar](max) NULL
)

这是我流畅的映射:

modelBuilder.Entity<Product>()
            .Map(m =>
            {
                m.Properties(t => new { t.Id, t.Name });
                m.ToTable("Product");
            })
            .Map(m =>
            {
                m.Properties(t => new { t.Id, t.Details});
                m.ToTable("ProductDetails");
            });

我希望能够在不加载详细信息字段的情况下显示产品列表。 但是,每当我加载产品时,它总是会进行INNER JOIN。 我希望它只从Product读取,但在读取Details属性时从ProductDetails读取。

怎么能实现这一目标?

如果不可能,我还能如何实现延迟加载属性?

表拆分是不可接受的,因为这意味着持久性机制正在规定域的设计。

在CodeCaster的回答后编辑:

域是固定的 - 我不想要一个引入ProductDetails实体的解决方案。 这个问题是关于持久存在的域模型。 改变域名不回答问题。

如何实现[分割表中的延迟加载标量属性]?

如果不可能,我还能如何实现延迟加载属性?

不能 ,延迟加载只适用于导航属性

如果你改变你的模型:

public class Product
{ 
    public virtual Guid Id {get;set;}
    public virtual string Name {get;set;}

    public virtual ProductDetails Details {get;set;}
}

public class ProductDetails
{ 
    public virtual Guid Product_Id {get;set;}
    public virtual string Details {get;set;}
}

您可以使用延迟加载,只有在获得Product.Details属性时才会查询ProductDetails

[这]是否意味着持久性机制正在规定域的设计?

实体模型不必是域模型。

您可以使用我在项目中使用的以下类:

/// <summary>
/// Wrapper class for an unlimited size string property 
/// to allow for lazy loading with Entity Framework.
/// </summary>
public class Text
{
    [MaxLength]
    public string Value { get; set; }

    public static implicit operator string(Text val)
    {
        return val.Value;
    }

    public static implicit operator Text(string val)
    {
        return new Text { Value = val };
    }

    public override string ToString()
    {
        return Value;
    }
}

由于该类重写了隐式运算符,因此您可以将Text类型的对象视为普通字符串:

Text myText = "Hello Text";

在您的实体类中,您可以简单地创建一个虚拟(延迟加载)属性:

public virtual Text Comment { get; set; }

您可以使用匿名类型加载实体的一部分,您只是无法将部分实体加载到同一实体类中。 (或者,你可以“手动”。)

var products =
   context
   .Products
   .Select(p => new {
      p.ID,
      p.Name
   }).AsEnumerable() // come out of EF
   .Select(anon => new Product { // manually load into product objects
      ID = anon.ID,
      Name = anon.Name
   }).ToList();

也可以只使用匿名类型或其他类型。

但是,您还必须稍后“手动”加载Details属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM