簡體   English   中英

實體框架延遲和急切加載返回 System.Data.Entity.DynamicProxies.PropertyName

[英]Entity Framework Lazy and Eager loading returns System.Data.Entity.DynamicProxies.PropertyName

我正在使用 Code First 方法學習實體框架。 我有兩個具有一對多關系的類:

public class Product
{
    [Key] 
    public int ProductID { get; set; } 
    public string ProductName { get; set; }

    //Foreign Key -----> To establish relationship btw two tables.
    public int CategoryID { get; set; }
    // A product belongs to a ----> Category
    public virtual ProductCategory Category { get; set; }

}

public class ProductCategory
{
    [Key] //PK
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    // A Category ----> has many products (List of Products)
    public virtual List<Product> ProductList { get; set; }    
}

我的 DbContext 類:

class ModelDBEntitiesContext2 : DbContext
{
    public ModelDBEntitiesContext2()
    {
        //turns off easy loading for all Entities---> use Eager loading to load related Entities by using "Include"
        this.Configuration.LazyLoadingEnabled = false;
    }

    public DbSet<Product> products { get; set; }
    public DbSet<ProductCategory> categories { get; set; }
}

我使用 linq 方法語法使用 INCLUDE (Eager Loading) 字詞查詢所有產品和所有產品及其類別,如下所示:

 ModelDBEntitiesContext2 db = new ModelDBEntitiesContext2();
 var pppp = db.products.Include(c => c.Category).ToList();

 //I bind it to a datagrid view            
 dataGridView.DataSource = pppp;

對 dataGridView 的兩個查詢結果顯示客戶的列返回System.Data.Entity.DynamicProxies.ProductCategory DataGridView Result

我真的做錯了什么? 為什么即使使用包含,我也無法檢索所有產品的類別。

通過將子類導航屬性標記為虛擬,EF會使用代理將引用包裝起來,以啟用延遲加載和更改跟蹤,無論您是否渴望加載。 如果刪除虛擬聲明,它將保留引用作為“類別”,但是,您將始終需要隨時加載該屬性,否則它將作為#null返回。 但是,在大多數情況下,您不應該這樣做,因為使用EF的目的是用於諸如變更跟蹤之類的事情。

擴展彼得和羅伯特的建議:

var pppp = db.products.Include(p => p.Category).ToList();
foreach(var p in pppp)
{
  if (p.Category != null)
    Console.WriteLine(p.Category.CategoryName); // not WriteLine(p.Category)
}

要么將以下內容添加到您的Category類:

public override string ToString()
{
   return CategoryName;
}

當您將對象傳遞到WriteLine等函數中時,它們希望使用字符串,該代碼將針對其他類型調用.ToString()。 .ToString()在類上的默認行為是返回類型名稱。

嘗試在您的項目 BbContext 構造方法中禁用 ProxyCreationEnabled:

Configuration.ProxyCreationEnabled = false;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM