我有三个表(此问题的简化示例):
模型是使用 EntityFramework 数据库优先方法生成的。
所有者模型
public partial class Owner
{
public Owner()
{
this.OwnerDogMapper= new HashSet<OwnerDogMapper>();
}
public string OwnerId { get; set; }
public string OwnerName { get; set; }
public virtual ICollection<OwnerDogMapper> OwnerDogMapper{ get; set; }
}
狗桌
public partial class Dog
{
public Dog()
{
this.OwnerDogMapper= new HashSet<OwnerDogMapper>();
}
public string DogId { get; set; }
public string DogName { get; set; }
public virtual ICollection<OwnerDogMapper> OwnerDogMapper{ get; set; }
}
以及映射表:OwnerDogMapper
public partial class OwnerDogMapper
{
public string OwnerId { get; set; }
public string DogId { get; set; }
public virtual Owner Owner { get; set; }
public virtual Dog Dog { get; set; }
}
现在,我尝试连接这三个表,并在传递 OwnerId 时获取 OwnerName 和 DogName。这是我的查询:
var output = await (from o in db.Owner
join odm in db.OwnerDogMapper on o.OwnerId equals odm.OwnerId
join d in db.Dog on odm.DogId equals d.DogId
where o.OwnerId == '01'
select new { o.OwnerName, d.DogName }
).ToListAsync();
但是它抛出了一个异常:
例外: “ObjectContent`1”类型未能序列化 内容类型“application/xml”的响应正文;字符集=utf-8'。
类型 '<>f__AnonymousType2`2[System.String,System.String]' 不能 连载了。考虑使用 DataContractAttribute 对其进行标记 属性,并标记您想要序列化的所有成员 DataMemberAttribute 属性。如果类型是集合,请考虑 使用 CollectionDataContractAttribute 对其进行标记。参见微软 其他受支持类型的 .NET Framework 文档。
DataLayer 将模型返回到 BusinessLayer,其中使用 AutoMapper 完成 DTO 映射。 EF 生成的模型中没有任何 DataContract。另外,到目前为止,在项目中,我没有直接从 DataLayer 传递 DTO。
如果我使用类似于Entity Framework Join 3 Tables
中提到的Lambda表达式var output = await db.Owner
.Where(o => o.OwnerId == "01")
.Include(odm => odm.OwnerDogMapper.Select(d => d.Dog))
.ToListAsync();
但是,就我而言,[Owner] 和 [Dog] 表之间没有任何关系。通过这个巴巴查询,它进入无限循环,我得到一个“StackOverflowException”:D -
“确保没有无限循环或无限递归
表映射或生成的模型是否存在根本性错误?还是我的查询不对?
后来我发现了这个问题。我必须更改 WebAPIconfig.cs 文件中的 configFormatter:
config.Formatters.Remove(config.Formatters.XmlFormatter);
删除它后,LINQ 查询就按预期工作。好像已经默认应用了。