简体   繁体   English

实体框架延迟和急切加载返回 System.Data.Entity.DynamicProxies.PropertyName

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

I am learning Entity framework using Code First approach.我正在使用 Code First 方法学习实体框架。 I have two clases with a relationship of one to many:我有两个具有一对多关系的类:

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; }    
}

My DbContext class:我的 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; }
}

I use linq method syntax to query for all the Products and all the Products with their category using the INCLUDE (Eager Loading) word as follow:我使用 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;

The result of both query on the dataGridView shows the Customer's column return System.Data.Entity.DynamicProxies.ProductCategory DataGridView Result对 dataGridView 的两个查询结果显示客户的列返回System.Data.Entity.DynamicProxies.ProductCategory DataGridView Result

What am I really doing wrong?我真的做错了什么? Why I can't retrieve the Category with all the Products even using the Include.为什么即使使用包含,我也无法检索所有产品的类别。

By marking the child class navigation property as virtual, EF will wrap the reference with a proxy to enable lazy loading & change tracking, whether you eager load or not. 通过将子类导航属性标记为虚拟,EF会使用代理将引用包装起来,以启用延迟加载和更改跟踪,无论您是否渴望加载。 If you remove the virtual declaration it will leave the reference as a "Category", however you will need to always eager-load that property or it will be returned as #null. 如果删除虚拟声明,它将保留引用作为“类别”,但是,您将始终需要随时加载该属性,否则它将作为#null返回。 However, in most cases you shouldn't do this because the point of using EF is for things like change tracking. 但是,在大多数情况下,您不应该这样做,因为使用EF的目的是用于诸如变更跟踪之类的事情。

To expand on Peter & Robert's suggestion: 扩展彼得和罗伯特的建议:

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)
}

Either that or add the following to your Category class: 要么将以下内容添加到您的Category类:

public override string ToString()
{
   return CategoryName;
}

When you pass an object into functions like WriteLine etc. where they expect to work with strings, that code will call .ToString() against other types. 当您将对象传递到WriteLine等函数中时,它们希望使用字符串,该代码将针对其他类型调用.ToString()。 The default behaviour of .ToString() on a class is to return the type name. .ToString()在类上的默认行为是返回类型名称。

尝试在您的项目 BbContext 构造方法中禁用 ProxyCreationEnabled:

Configuration.ProxyCreationEnabled = false;

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

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