簡體   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