【问题标题】:How to easly convert linq result to Business Object Collection <T>如何轻松地将 linq 结果转换为业务对象集合 <T>
【发布时间】:2011-06-19 18:53:49
【问题描述】:

我有业务对象集合

我想使用 linq 过滤行,但注意到它返回的 IEnumerable 不能转换到我的 BOC

例如,我不能这样做

BOC <Client> bocCLients = (BOC <Client>) 
                          from C in ClientsColl where C.ClientId == 100 select C

我已经通过循环 linq 结果并将返回的对象添加到我的原始集合中解决了这个问题。

不知道有没有更简单的方法?

【问题讨论】:

    标签: linq casting business-objects


    【解决方案1】:

    这看起来是创建扩展方法的绝佳机会。从您的问题来看,ClientsColl 似乎已经包含 Client 类型的对象。在这种情况下,您的 foreach 循环解决方案是理想的。但是,您可以将该解决方案封装到扩展方法中,使其可重用且易于阅读。

    以下是它的外观示例:

     public static BOC<T> ToBOC<T>(this IEnumerable<T> sourceCollection)
     {
         var boc = new BOC<T>();
         foreach (T item in sourceCollection)
         {
             boc.Add(item);
         }
         return boc;
     }
    

    使用此扩展方法,您只需将查询编写如下:

    BOC<Client> bocClients =
    (
        from C in ClientsColl
        where C.ClientID == 100
        select C
    ).ToBOC();
    

    编辑

    跟进 ICollection 更通用的扩展方法的想法,但保持原来的问题是对特定类型的集合执行某种强制转换,现在有了 BOC 实现 ICollection 的新信息,这里有一个更通用的扩展方法和执行工作的用法:

    public static TCollection ToICollection<T, TCollection>(this IEnumerable<T> sourceCollection)
            where TCollection : ICollection<T>, new()
        {
            TCollection col = new TCollection();
            foreach (T item in sourceCollection)
            {
                col.Add(item);
            }
            return col;
        }
    

    及用法:

    BOC<Client> bocClients2 =
    (
        from C in ClientsColl
        where C.ClientID == 100
        select C
    ).ToICollection<Client, BOC<Client>>();
    

    这看起来更有用吗?让我知道你的想法。

    【讨论】:

    • @David 或 ICollection 的扩展方法,称为 AddRange,执行上述操作。将致力于任何收藏,而不仅仅是 BOC
    • 只要 BOC 对象实现 ICollection 也可以工作(我不能从提供的问题细节中假设)。我不会称它为 AddRange,因为您正在尝试转换为一个类型并返回该类型,而不是将项目添加到现有集合中,对吗?此外,我还编写了另一个扩展方法,它采用 Func 以防您的 ClientsColl 不包含 Client 对象而是包含一些 ORM 实体,例如。
    • 使用您的 AddRange 扩展方法,您需要一个 BOC 实例,因此语法为 BOC bocClients = new BOC().AddRange( ... 您的 linq 查询这里...)
    • public static void AddRange(this ICollection sourceCollection, IEnumerable addItems) { foreach (T item in addItems) { sourceCollection.Add(item); } }
    • @David 是的,你是对的,不能假设 ICollection 已实现,但它应该是任何类型的集合。
    【解决方案2】:
    var bocCLients = ClientsColl.Where(c => c.ClientId == 100).ToList();
    

    或者

    var bocCLients = new BOC<Client>(ClientsColl.Where(c => c.ClientId == 100));
    

    编辑 或者可能是 AddRange 扩展

    public static void AddRange<T>(this ICollection<T> colSource, IEnumerable<T> collection)
            {
                if (colSource is List<T>)
                    ((List<T>)colSource).AddRange(collection); //If List use build in optimized AddRange function
                else
                {
                    foreach (var item in collection)
                        colSource.Add(item);
                }
            }
    

    【讨论】:

    • 感谢您的好提示,但 #1 创建列表 ,而不是 BOC,我认为 #2 需要额外的 BOC 构造函数接受 IEnumerabel?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    相关资源
    最近更新 更多