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

问题描述 投票:0回答:1

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

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

基线场景包含两个具有“多对多”关系的对象A和B,如下所述:

enter image description here

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的虚拟属性。

我在控制器上尝试的代码虽然使用“LazyLoading”方法,但在每个关联的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,
                    };

返回:

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

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

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

c# ef-code-first entity-framework-4 lazy-loading asp.net-apicontroller
1个回答
0
投票

我建议创建一个额外的自定义对象并映射字段(手动或使用像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返回数据库实体并不一定是个好主意(以及其他一些原因,例如您可能不希望第三方使用您的API来查看数据库中的每个属性)。

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

© www.soinside.com 2019 - 2024. All rights reserved.