2017-05-17 35 views
0

我得到EF的自我引用问题,我试图结束它,但仍然允许服务能够执行一个GET {[FromODataUri]诠释键}传递一个密钥和如有必要,返回一个IQuerable对象来获取扩展表。以下是这些表格的精简版本。有关如何处理这种情况的任何建议。EF WebAPI自回参考循环

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,但不是必需的。按照惯例,它不必被PK DataAnnotation覆盖。

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;} 
} 
+0

的WebAPI被序列化您的回复,但是产品参考人,其中引用了一个产品,它引用的人,其引用的产品。您可能需要重新考虑是否有必要在您的People类中使用Product,或者可能会将您的实体映射到避免此循环引用的DTO。 – Tom

+0

我应该补充说,这可能是启用了“延迟加载”的症状,因为序列化程序正在查看属性并加载实体。 – Tom

+0

可能的重复http://stackoverflow.com/questions/19467673/entity-framework-self-referencing-loop-detected – Tom

回答

0

我一段时间后想通了这一点。如果您从APIController继承,但是如果您切换到从ODataController继承,则一切正常。

所以

public class MyController : ApiController 
    { 
    ..... Bunch of code here 
    } 

public class MyController : ODataController 
    { 
    ..... Bunch of code here 
    } 
0

在这种情况下,我建议使用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); 
} 

注意,这种方法是使用查询字符串参数

+0

这不会总是返回所有关联的表?例如,如果我翻转这个arround,我做了一个产品'code var rslt = db.Products.Select(x => new {x.ProductId,x.ProductName,new List (){y = y.PeopleId ,y.PeopleName,y.ProductId}; code'会在每次调用中带回所有产品和所有人? –

+0

vs使用Odata Query,在那里我可以让GET产品它只会返回我的产品,它不会' t返回任何关联的数据除非我将?$ expand = People添加到我的QueryString –

+0

@JoeRicklefs yes它会,如果你想在.toList()this之前搜索一个特定的id add:Where(x => x.PeopleId = = key).toList(), –