我正在尝试创建一个WebAPI,返回Json数据供jQuery使用。这是相当简单的数据。。。一个类别,每个类别下都有一个网站链接列表,每个链接都有标题和URL。我用静态数据对它进行了模拟,效果很好。现在,我正努力转向实时数据。我有一张带有类别id和类别标题的表。另一个表包含链接id、类别id、链接标题和链接URL。
这代表了我如何需要链接数据与只列出一次的类别嵌套:
LegalLinks[] legalLinks = new LegalLinks[]
{
new LegalLinks {
Id = 1,
Title = "Test Category One.1",
Links = new LinkDetails[]
{
new LinkDetails { Title = "Link One", Link = "http://www.google.com/" },
new LinkDetails { Title = "Link Two", Link = "http://www.google.com/" }
}
},
new LegalLinks {
Id = 2,
Title = "Test Category Two.2",
Links = new LinkDetails[]
{
new LinkDetails { Title = "Link Three", Link = "http://www.google.com/" },
new LinkDetails { Title = "Link Four", Link = "http://www.google.com/" },
new LinkDetails { Title = "Link Five", Link = "http://www.google.com/" }
}
}
};
我能够成功地只返回类别数据。我失败的地方是嵌套的链接数据。以下是我的型号:
public class LegalLinks_categoriesDTO
{
public int CategoryId { get; set; }
public string Category { get; set; }
public virtual IEnumerable<LegalLinks_linksDTO> Links { get; set; }
}
public class LegalLinks_linksDTO
{
public string Title { get; set; }
public string LinkURL { get; set; }
}
还有我的API控制器:
private LegalLinksContext db = new LegalLinksContext();
public IQueryable<LegalLinks_categoriesDTO> GetLegalLinks()
{
var legalLinks = from category in db.Categories
join link in db.Links on category.Id equals link.CategoryId into categoryLinks
from l in categoryLinks.DefaultIfEmpty()
orderby category.Title
select new LegalLinks_categoriesDTO()
{
CategoryId = category.Id,
Category = category.Title,
Links = new LegalLinks_linksDTO { Title = l.Title, LinkURL = l.LinkURL }
};
return legalLinks;
}
我收到一个错误,无法将类型LegalLinks_linksDTO转换为IEnumerable LegalLinks_linksDTO。在过去的6个小时里,我尝试了这句话的不同变体,阅读了所有关于Linq和joins的文章。如何正确嵌套联接数据?
编辑1
好的,我找到了一个可行的解决方案,使用子选择。不确定这是否是最有效的方法,但它可以工作,并以我需要的方式返回数据
private IQueryable<LegalLinks_categoriesDTO> GetLegalLinks()
{
var legalLinks = from category in db.Categories
orderby category.Title
select new LegalLinks_categoriesDTO()
{
CategoryId = category.Id,
Category = category.Title,
Links = from a in db.Links
where a.CategoryId == category.Id
select new LegalLinks_LinkDetails
{
Title = a.Title,
LinkURL = a.LinkURL
}
};
return legalLinks;
}
问题是您正试图将LegalLinks_linksDTO
分配给IEnumerable<LegalLinks_linksDTO>
。这行不通。
但是,您可以在不使用DefaultIfEmpty()
的情况下保持分组。示例:
var legalLinks = from category in db.Categories
join link in db.Links on category.Id equals link.CategoryId into categoryLinks
orderby category.Title
select new LegalLinks_categoriesDTO()
{
CategoryId = category.Id,
Category = category.Title,
Links = categoryLinks.Select(l => new LegalLinks_linksDTO { Title = l.Title, LinkURL = l.LinkURL })
};
return legalLinks;
我删除了from l in categoryLinks.DefaultIfEmpty()
语句,并在一个匿名对象中收集了链接的类别和相对组,然后从该对象中投影了_categoriesDto
的实例,并在其初始值设定项列表中,为属于给定类别的链接组的每个项创建了_linksDTO
的实例。
var legalLinks = from category in db.Categories
join link in db.Links on category.Id equals link.CategoryId into categoryLinks
orderby category.Title
select new { category, links = categoryLinks.DefaultIfEmpty() } into dto
select new LegalLinks_categoriesDTO()
{
CategoryId = dto.category.Id,
Category = dto.category.Title,
Links = dto.links.First() != null ? dto.links.Select(lnk => new LegalLinks_linksDTO { Title = lnk.Title, LinkURL = lnk.LinkUrl }) : null
};
这也适用于没有链接的类别,属性链接将为null(但您最终可以为其指定默认值)。。