2016-12-01 184 views
2

你好关系的不需要的加载,在EF核心

我有问题,EF核心的功能 - 它可以自动绑定相关实体一起当实体某处独立地连接到当前dbCotnext。

假设以下两个实体:

public class Seller { 
     public Guid Id {get;set;} 
     public List<Product> Products {get;set;} 
    } 

    public class Product { 
     public Guid Id {get;set;} 
     public Guid SellerId {get;set;} 
     public Seller Seller {get;set;} 
    } 

和Controller(只是想象)一些代码:

var seller = DbContext.Sellers.FirstOrDefault(e => e.Id == someId); 
var products = DbContext.Products.All(t => t.SellerId == someId); 
return StatusCode(200, products); 

返回的JSON会像

[ 
    { 
     "id": "1234", 
     "sellerId": "5678", 
     "seller": { 
      "id" : "5678", 
      "products": ["(muted reference loop exception from json converter here.)"] 
     } 
    } 
] 

但我不希望卖家被包含在每个产品中。如果我这样做,我会打电话Products.Include(...)为那个或别的东西。 我不想通过实体进行爬网并且无法导航属性。 我不想用[JsonIgnore]将其隐藏,因为有时必须包含关系。 当发生这种情况时,我也不想手动分离每个实体。

问题是,有没有什么办法可以禁用或解决此问题?

感谢

+0

尝试'公开名单产品{获得;设置;}'变化可空 –

回答

3

不,你不能/不应该。你需要单独的dto类(es)。

Newtonsoft.Json负责对象序列化,它决定哪些属性必须被序列化。您只能使用它的属性来控制它的行为。你不能从EF控制它:)

而且只要你希望有时包括财产,有时不需要 - 你需要两个不同的类(每个类都有正确的属性)。其他一切都是黑客。 DTO,Automapper和所有这些东西 - 欢迎您。

顺便说一句,具有不同的外部API和内部数据存储类,可以让您轻松更改一个而不会破坏其他(将来)。

1

你必须改变模型类和使用可空类型

public class Product { 
     public Guid Id {get;set;} 
     public Guid SellerId {get;set;} 
     public Seller? Seller {get;set;} 
    } 
+1

问题是关于'Product.Seller' – Dmitry

0

你尝试过在启动类此配置:

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 

    services.AddMvc().AddJsonOptions(a => a.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore); 

    // other code 
} 
+1

问题不是循环,关于“卖方”的财产。 – Dmitry

+0

卖方是产品内的导航属性,您可以禁用引用循环来序列化结果而不用循环引用,我同意你关于DTO,但并不总是所有开发人员都使用DTO,它将要避免的第一个问题版本循环引用的行为以及您可以处理的这段代码 –

+0

'Project.Seller'不是循环引用('Project.Seller.Projects')。 – Dmitry