如何避免使用 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。
我正在尝试使用以下对象作为 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。