2015-04-16 84 views
2

我目前正在使用MVC從3個不同的數據庫中搜索並返回結果。每個數據庫的結果被放入一個包含來自所有DB的公共字段的一組SoftwareLight對象中,以及一個Context屬性以指示結果來自哪個數據庫。到目前爲止,這部分工作很好。將列表中的對象與枚舉聯繫起來

現在我要做的是將每個具有相同名稱但來自不同上下文的SoftwareLight對象合併爲一個條目。理想情況下,此「合併」條目的Context屬性也將包含所有發現它的上下文...

給你一個這些結果集可能看起來像什麼樣的小例子,以及我想要最終實現,請參閱下文。但主要是我的問題有以下幾點:

  1. 我怎樣才能讓Context酒店在一次接受多個枚舉項? (我已經看到這樣做使用單個&或單個|和後來檢查使用Enum.HasFlag();方法?)
  2. 如何有效地將具有相同名稱的結果合併/合併到單個條目中?

[EDIT]根據要求,我添加了SoftwareLight類和Context enum聲明。

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? 

當前結果,搜索術語中 「Dreamweaver」:

 
    |---------------------------------------------------------| 
    | 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  | 
    |---------------------------------------------------------------------| 
+0

你能澄清你的問題,通過(1)提供的聲明(2)指定上下文爲「NET」的「Adobe Dreamweaver」是否可能具有「Public Facing」=否,但上下文「LOCAL」具有「Public Facing」= Yes? – Alex

+0

所需信息已添加到問題中。謝謝! – MaxOvrdrv

回答

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)) 
    }); 
+0

我會看看...這將回答合併問題,但不是枚舉,因爲您將結果放入列表中...我想重新使用'SoftwareLight'對象並使上下文成爲一個單一的枚舉而不是一個列表...我會測試這個,並讓你知道。就其他領域而言,我對這些領域有要求,所以這不是問題。 :)但很好,趕上! :) – MaxOvrdrv

+0

好的。根據要求,你能否提供這兩個問題的答案,然後我可以相應地更新這個答案。 – Alex

+0

PublicFacing需要「如果有的話是真的,那麼真的」......第二個問題是什麼? – MaxOvrdrv

0

由於標誌只是整數,您可以輕鬆地總結起來在group子句。

假設你的背景是這樣的:

[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) 
    };