【问题标题】:How to successfully join two in-memory linq collections?如何成功加入两个内存中的 linq 集合?
【发布时间】:2009-04-09 17:08:17
【问题描述】:

我正在尝试加入一个来自数据库的 Linq 集合和一个来自 XML 文件的集合。这可能吗?我总是得到:本地序列不能用于 LINQ to SQL 实现的查询运算符,但 Contains() 运算符除外。

这是我的代码:

MyDataContext dc = new MyDataContext();
XElement CustomData;

var pages = from p in dc.Pages
            select new
            {
                Title = p.Title,
                Slug = p.Slug,
                PageId = p.PageId.ToString()
            };

var orders = from p in CustomData.Element("pages").Elements("page")
             select new
             {
                 PageId = (string)p.Attribute("id"),
                 SortOrder = (int)p.Attribute("sortOrder")
             };


var source = from p in pages
             join o in orders
             on p.PageId equals o.PageId
             select p;

source.ToList();

【问题讨论】:

    标签: asp.net linq


    【解决方案1】:

    我认为你根本不需要加入。

    MyDataContext dc = new MyDataContext();
    XElement CustomData;
    
    var orders = CustomData.Element("pages").Elements("page")
                           .Select( o =>  new
                             {
                                 PageId = p.Attribute("id").ToString(),
                                 SortOrder = (int)p.Attribute("sortOrder")
                             });
    
    var source = dc.Pages
                   .Where( p => orders.Select( o => o.PageId)
                                      .Contains( p.PageId.ToString() ))
                   .Select( p => new
                    {
                      Title = p.Title,
                      Slug = p.Slug,
                      PageId = p.PageId.ToString()
                    });
    

    【讨论】:

    • 其实我的情况稍微复杂一点。我降低了复杂性以解决问题,您帮助我完成了第一个示例。我已经在尝试转换为列表,但是加入后我会得到空集。问题是Guids被转换为大写字符串,我加入了小写:)
    • 这个更新的例子很有趣,但显示了一些错误:“方法的类型参数 'System.Linq.Enumerable.Contains(System.Collections.Generic.IEnumerable, TSource)'无法从用法中推断出来。尝试明确指定类型参数。”导致 .Contains(p.PageId)
    • @Milan -- PageID 是整数还是字符串?我错误地认为您已将 PageId 转换为 int(误认为是 SortOrder)。如果是 int,则尝试按顺序将其转换为 int(我将更新我的示例)。
    • 那么可能应该将它们作为字符串进行比较。
    【解决方案2】:

    您似乎无法通过延迟执行来连接本地集合(订单)和 LINQ2SQL 结果。您可以执行页面查询 ToList(就像 tvanfosson 最初建议的那样:))或者可能执行类似的操作...

    var source = from p in pages
                 where orders.Select(o=> o.PageID).Contains(p.PageID)
                 select p;
    

    这不是您要查找的连接,但如果您想要延迟执行 LINQ2SQL,您可以这样。

    【讨论】:

    • 由于他只是从页面中选择,我认为没有必要加入。我已经相应地修改了我的答案。与您的类似,但它使用扩展方法。
    • 我的真实情况稍微复杂一些。我使用“订单”中的一列,并且我已经有了 where ...Contains 子句用于其他内容。无论如何,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 2017-08-10
    • 2020-09-03
    • 1970-01-01
    • 2021-11-25
    相关资源
    最近更新 更多