使用枚举连接列表中的对象

时间:2015-04-16 14:34:47

标签: c# asp.net-mvc-4

我目前正在使用MVC搜索并返回3个不同数据库的结果。每个数据库的结果放在一组SoftwareLight个对象中,这些对象包含来自所有数据库的公共字段,以及一个Context属性,用于指示结果来自哪个数据库。那部分到目前为止效果很好。

现在我要做的是将具有相同名称但来自不同上下文的每个SoftwareLight对象组合到一个条目中。理想情况下,这个"的Context属性合并了#34;条目也将保留所有发现的背景......

为了举例说明这些结果集的外观,以及我最终要达到的目标,请参阅下文。但主要是,我的问题如下:

  1. 如何让Context属性一次接受多个枚举条目? (我已经看到使用单个&或单个|完成此操作,之后使用Enum.HasFlag();方法进行了检查?)
  2. 如何有效地将具有相同名称的结果合并/合并到一个条目中?
  3. [编辑]根据要求,我添加了SoftwareLight类和Context枚举声明。

     public class SoftwareLight : IEquatable<SoftwareLight>
     {
        public string Name { get; set; }
        public string Version { get; set; }
        public int? Installs { get; set; }
        public AppContext Context { get; set; }
        public bool External { get; set; }
     }
    
    [Flags]
    public enum AppContext
    {
        NET,
        LOCAL,
        LICENSES
    }
    

    当前搜索代码的示例:

            //Current searching method...
            NET_DATA db1 = new Model.NET_DATA();
            LOCAL_DATA db2 = new Model.LOCAL_DATA();
            LICENSING_DATA db3 = new Model.LICENSING_DATA();
    
            List<SoftwareLight> finds = new List<SoftwareLight>();
    
            //SoftwareLight items returned have their Context Property set to 'NET'
            finds.AddRange(db1.Find(searchterms));
            //SoftwareLight items returned have their Context Property set to 'LOCAL'
            finds.AddRange(db2.Find(searchterms));
            //SoftwareLight items returned have their Context Property set to 'LICENSES'
            finds.AddRange(db3.Find(searchterms));
    
            finds = finds.OrderBy(a => a.Name).ToList();
    
            //HOW DO I COMBINE THEM HERE?
    

    当前结果的示例,搜索术语&#34; Dreamweaver&#34;:

        |---------------------------------------------------------|
        | Product Name      | Context  | Public Facing | Installs |
        |---------------------------------------------------------|
        | Adobe Dreamweaver | NET      | No            | 23       |
        |---------------------------------------------------------|
        | Adobe Dreamweaver | LOCAL    | No            | 7        |
        |---------------------------------------------------------|
        | Adobe Dreamweaver | LICENSES | No            | 9        |
        |---------------------------------------------------------|
    

    想要结果的示例,搜索术语Dreamweaver:

        |---------------------------------------------------------------------|
        | Product Name      | Context              | Public Facing | Installs |
        |---------------------------------------------------------------------|
        | Adobe Dreamweaver | NET, LOCAL, LICENSES | No            | 39       |
        |---------------------------------------------------------------------|
    

2 个答案:

答案 0 :(得分:2)

您似乎需要GroupBy而不是OrderBy

所以不要做

finds = finds.OrderBy(a => a.Name).ToList();

你应该这样做:

var myGroups = finds
   .GroupBy(a => a.Name)
   .Select(g => new SoftwareLight() {
        Name = g.Key,
        // What should be done with the version field?
        // Right now, I am concatenating distinct versions.
        Version = string.Join(", ", g.Select(v => v.Version).Distinct()),
        // "OR" through aggregation.
        Context = g.Aggregate((AppContext)0, (c, v) => (AppContext)(c | v.Context)),
        // True if any is public facing
        External = g.Any(v => v.External),
        Installs = g.Sum(v => v.Installs))
    });

答案 1 :(得分:0)

由于标志只是整数,因此您可以在组子句中轻松总结它们。

假设您的上下文如下所示:

[Flags]
public enum Context
{
    NET = 1,
    LOCAL = 2,
    LICENSES = 4
}

public class Product
{
    public Context Context;
    public string Name;
}

Product[] items = new[]
{
    new Product { Name = "Adobe", Context = Context.NET },
    new Product { Name = "Adobe", Context = Context.LICENSES },
    new Product { Name = "Adobe", Context = Context.LOCAL },
    new Product { Name = "Adobe2", Context = Context.LOCAL },
    new Product { Name = "Adobe2", Context = Context.NET }
};

您可以使用此语句实际获取组合枚举:

var result = from item in items
    group item by item.Name
    into itemGroup
    select new
    {
        itemGroup.Key,
        Context = (Context)itemGroup.Sum(x => (int)x.Context)
    };