C# EF WebAPI自引用循环
我在EF中遇到了一个自引用问题,我正在努力克服它,但仍然允许服务能够执行一个GET传递{[FromODataUri]int key}一个key,并在必要时返回一个IQuerable Obj以获得扩展表。下面是表格的精简版本。关于如何处理这种情况的任何建议C# EF WebAPI自引用循环,c#,entity-framework,asp.net-web-api,C#,Entity Framework,Asp.net Web Api,我在EF中遇到了一个自引用问题,我正在努力克服它,但仍然允许服务能够执行一个GET传递{[FromODataUri]int key}一个key,并在必要时返回一个IQuerable Obj以获得扩展表。下面是表格的精简版本。关于如何处理这种情况的任何建议 public class People { public int PeopleId {get;set;} public string PeopleName {get;set;} public int? ProductId{get;set
public class People
{
public int PeopleId {get;set;}
public string PeopleName {get;set;}
public int? ProductId{get;set;}
public virtual Product Product{get;set;}
}
ProductId是产品中的主键,但不是必需的。按照惯例,它不必用PK DataAnnotation overide修饰
public class Product
{
public Product()
{
PeopleCollection = HashSet<People>();
}
public int ProductId {get;set;}
public string ProductName {get;set;}
public virtual ICollection<People> Peoples{get;set;}
}
公共类产品
{
公共产品()
{
PeopleCollection=HashSet();
}
public int ProductId{get;set;}
公共字符串ProductName{get;set;}
公共虚拟ICollection用户{get;set;}
}
在这种情况下,我建议使用DTO或匿名对象,例如:
public IHttpActionResult Get() {
var response = db.YourTable.Select(x=>new{
x.PeopleId,
x.PeopleName,
x.ProductId,
Product= new {
x.ProductId,
x.ProductName
}
}).toList();
return Ok(response);
}
这就是我如何处理匿名对象的方法,如果你想使用DTO,你只需要映射它们,希望这就是你想要的
仅针对特定id:
public IHttpActionResult Get(int id) {
var response = db.YourDb.Select(x=>new{
x.PeopleId,
x.PeopleName,
x.ProductId,
Product= new {
x.ProductId,
x.ProductName
}
})Where(x=>x.PeopleId == id).toList();
return Ok(response);
}
注意,这个方法使用的是查询字符串参数我过了一段时间才发现这一点。如果从ApitController继承,但如果切换到从ODataController继承,则会出现自引用问题 所以 到
WebAPI正在序列化您的响应,但产品引用人,它引用产品,它引用人,它引用产品。您可能需要重新考虑是否需要在您的
人员
类上设置产品
,或者可能需要将您的实体映射到避免此循环引用的DTO。我应该补充,这可能是启用延迟加载
的症状,因为序列化程序正在查看属性,然后加载实体。可能的重复项不总是返回所有关联的表吗?例如,如果我翻转此区域,然后对产品执行get操作code var rslt=db.Products.Select(x=>new{x.ProductId,x.ProductName,new List(){y=y.PeopleId,y.PeopleName,y.ProductId};code
将返回每次通话中的所有产品和所有人员?与使用Odata查询相比,我只需访问产品,它将只返回我的产品,并且不会返回任何相关数据,除非我将?$expand=人员添加到我的QueryString@JoeRicklefs是的,如果您想在添加之前搜索特定的id,它会。toList()this:Where(x=>x.PeopleId==key),除非此服务通过URL查询,我不知道将发送哪些字段/或条件。因此,解决方案需要更灵活。如果用户只发送一个Get-to api/人员,服务将只返回人员信息,但如果他们发送api/人员?$expand=产品,结果将包括:删除人员和相关产品。@JoeRicklefs哦,我明白了,a找到了一本非常好的微软指南:
public class MyController : ApiController
{
..... Bunch of code here
}
public class MyController : ODataController
{
..... Bunch of code here
}