【问题标题】:Linq to Entities - OrderBy Tags (many to many relationship)Linq to Entities - OrderBy 标签(多对多关系)
【发布时间】:2013-06-03 09:04:45
【问题描述】:

asp.net mvc 4、实体框架 5、SQL Server 2012 Express、代码优先

我有一个 Place 模型:

public virtual int PlaceID { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public virtual string Name { get; set; }

以及相关的Tag模型:

public virtual int TagID { get; set; }
public virtual string Name { get; set; }
public virtual string NamePlural { get; set; }
public virtual ICollection<Place> Places { get; set; }

他们有一个多对多的关系。

我正在选择所有带有“餐厅”标签的地方:

 List<Place> Restaurants = allPlaces.Where(
    p => p.Tags.Any(
       t => t.Name == "Restaurant")).OrderBy(p => p.Name).ToList();

我想按有序标签显示 - 然后按名称排序。

假设有 5 个地方:

My Cafe Bar, Tags="Restaurant", "Cafe", "Bar"
Another Cafe, Tags="Restaurant", "Cafe"
Marios Italian, Tags="Restaurant", "Italian", "Bar"
Donnies Pizzaria, Tags="Restaurant", "Italian"
A1 Chinese, Tags="Restaurant", "Chinese"
Fusion One, Tags="Restaurant", "Chinese", "Italian"
China Garden, Tags="Restaurant", "Chinese"

我想按以下顺序输出(因为它们都是餐厅,所以不需要输出餐厅组):

>>Bars
Marios Italian
My Cafe Bar

>>Cafes
Another Cafe
My Cafe Bar

>>Chinese
A1 Chinese
Fusion One
China Garden

>>Italian
Donnies Pizzaria
Fusion One
Marios Pizzaria

在我看来,我想像上面那样显示它们 - 带有标题。

Linq 可以做到这一点吗?

谢谢。

【问题讨论】:

    标签: asp.net asp.net-mvc linq asp.net-mvc-4 linq-to-entities


    【解决方案1】:

    看起来您正在寻找GroupBy,而不是OrderBy。检查这个查询:

    var restaurants = allPlaces.Where(p => p.Tags.Any(t => t.Name == "Restaurant"))
                               .SelectMany(p => p.Tags, (p, t) => new { Tag = t.Name, Name = p.Name })
                               .GroupBy(i => i.Tag)
                               .Where(g => g.Key != "Restaurant")
                               .Select(g => new { Tag = g.Key, Places = g })
                               .ToList();
    

    它将产生一个具有两个属性的匿名对象列表:

    {
        public string Tag { get; set; }
        public List<string> Places { get; set;}
    }
    

    我很确定这里的逻辑,但不是关于 LINQ to Entities 对那里使用的所有东西的支持。

    【讨论】:

    • 谢谢。编译器不喜欢第二行中的“新”。
    • 更新了我的答案,请立即查看。
    • 看起来你是对的 :) LINQ to Entities 无法识别方法 'System.Collections.Generic.List1[&lt;&gt;f__AnonymousType52[System.String,System.String]] ToList[f__AnonymousType5 2](System.Collections.Generic.IEnumerable1[f__AnonymousType5`2[System.String,System.String]])' 方法,该方法不能翻译成store表达式。
    • 谢谢;这解决了一些问题。更深入地研究这个 - 我实际上需要其他可用的属性。例如 - 我需要的每个地方都有一个 URL 属性。返回地点和标签对象有多容易?或者,只需将 URL 属性添加到匿名对象即可...
    • 实际上我想我可以添加到 Name = p.Name 列表中。我想把它放在一个非匿名对象中 - 我该怎么做?
    【解决方案2】:

    我最终以不同的方式看待这个问题。

    我只是将所有 标签 传递给视图(按字母顺序排序) - 然后循环遍历它们。在遍历每个标签时,我会遍历其中的每个位置(导航属性)。

    问题的非常简单的解决方案:

    @foreach (var t in Model)
    {
       <h2>@t.Name</h2>
    
       foreach (var p in t.Places)
       {
           <li>@Html.ActionLink(p.Name, "Details", new { URL = p.URL })</li>
       }
    }
    

    【讨论】:

    • 这实际上被证明是有缺陷的,因为导航属性返回 every 位置,而不仅仅是正确标记的位置。请参阅上面的答案,了解我最后所做的修改版本。
    猜你喜欢
    • 2011-04-12
    • 1970-01-01
    • 2011-05-14
    • 2013-06-01
    • 2010-11-26
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多