【问题标题】:Entity Framework Lazy and Eager loading returns System.Data.Entity.DynamicProxies.PropertyName实体框架延迟和急切加载返回 System.Data.Entity.DynamicProxies.PropertyName
【发布时间】:2017-07-24 19:27:42
【问题描述】:

我正在使用 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

我到底做错了什么?为什么即使使用包含我也无法检索包含所有产品的类别。

【问题讨论】:

  • 但确实如此!由于它是一个复杂类型,它将显示一个类别的字符串表示。您应该设置列的正确字段名称,例如 CategoryName。
  • 将类别列绑定到类似Eval("Category.CategoryName")
  • @PeterBons @Robert McKee 我确实试过这个:var pppp = db.products.Include(p =&gt; p.Category.CategoryName).ToList(); 但有一个例外,The EntityType 'EFcodeFirst2.ModelEF.ProductCategory' does not declare a navigation property with the name 'CategoryName'.
  • 需要修复的不是EF查询,是datagridview列绑定。
  • @PeterBons 我不这么认为,因为我只是在控制台应用程序中尝试过,我得到了相同的结果“System.Data.Entity.DynamicProxies.ProductCategory”dropbox.com/s/7fl0kl8j8hbeq39/lazy2.PNG?dl=0

标签: c# entity-framework linq datagridview


【解决方案1】:

通过将子类导航属性标记为虚拟,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() 在类上的默认行为是返回类型名称。

【讨论】:

    猜你喜欢
    • 2011-03-14
    • 2013-09-25
    • 2021-10-21
    • 2014-02-18
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    相关资源
    最近更新 更多