Linq Result内部的嵌套联接数据

本文关键字:数据 嵌套 Result 内部 Linq | 更新日期: 2023-09-27 17:58:13

我正在尝试创建一个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;
    }

Linq Result内部的嵌套联接数据

问题是您正试图将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(但您最终可以为其指定默认值)。。