如何避免使用 Entity Framework 在关系引用循环中检索关系对象?

How to avoid retrieving relational objects within relational reference loop using Entity Framework?

我正在尝试使用以下对象作为 return 类型正确设计 Api 控制器方法的结构:

           var obj= new CustomObject
                    {
                        Id = a.Id,
                        stampleProperty= a.stampleProperty,
                        stampleProperty= a.stampleProperty2,
                        B= a.B,
                    };

基准场景由两个对象 A 和 B 组成,它们具有如下所述的 "Many to Many" 关系:

public class A
{

   public int AId { get; set; }
   public string sampleProperty{ get; set; }        
   public string sampleProperty2{ get; set; }

   public virtual ICollection B { get; set; }
}

public class B
{

   public int BId { get; set; }
   public string sampleProperty3{ get; set; }        
   public string sampleProperty4{ get; set; }
   public int  ComyId { get; set; }

   public virtual ICollection A{ get; set; }
   public virtual Comy Comy{ get; set; }
}

注意:我无法更改数据库的结构。此外,我寻求从 A 对象检索关系 B 对象的最佳方法,而无需 B 的 A 的虚拟属性。

我在控制器上尝试的代码,尽管它使用 "LazyLoading" 方法,returns 在每个关联的 B 类对象中嵌入了 A 类对象。

var a = db.A.FirstOrDefault(a => a.stampleProperty== stampleProperty);
var obj= new CustomObject
                    {
                        Id = a.AId,
                        sampleProperty= a.sampleProperty,
                        sampleProp= a.sampleProp,
                        B = a.B,
                    };

Return:

{
 "AId": 
 "sampleProperty":
 "sampleProp":
 "B":[{
      "BId":
      "sampleProperty3":
      "sampleProperty4":
      "ComyId":
      "A":[ **REFERENCE LOOP**  ]
      "ComyId":
      "Comy":{}
     }]
}

目标: B 对象没有 A 的虚拟属性。

由于我正在学习这个框架,我正在寻找使用这些工具的正确方法,避免原始 SQL 查询和多个请求。

我建议创建一个额外的自定义对象并映射字段(手动或使用像 AutoMapper 这样的框架)。

应用于您的示例可能类似于:

public class CustomObjectA
{
    public int Id { get; set; }
    public string stampleProperty { get; set; }
    public string stampleProperty2 { get; set; }
    public CusomObjectB[] B { get; set; }
}

public class CustomObjectB
{
    public int BId { get; set; }
    public string sampleProperty3{ get; set; }        
    public string sampleProperty4{ get; set; }
    public int ComyId { get; set; }
}

用法如下所示:

var a = db.A.FirstOrDefault(a => a.stampleProperty== stampleProperty);

var obj= new CustomObjectA
{
    Id = a.AId,
    sampleProperty= a.sampleProperty,
    sampleProp= a.sampleProp,
    B = a.B.Select(b => new CustomObjectB
    {
        BId = b.BId,
        sampleProperty3 = b.sampleProperty3

        //etc...
    }).ToArray()
};

出于这些原因(以及其他一些原因,例如您可能不希望第三方使用您的 API 以便能够查看数据库中的每个 属性。

这种方法的一个常用术语是使用 DTO(数据传输对象)。这是 Microsoft 的教程,他们在其中进一步讨论 https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5