2012-04-27 15 views
0

我設計的界面,用戶可以加入一個關鍵字publicaiton,當他們這樣做時,我想建議其他關鍵字通常與所選關鍵字一起出現。訣竅是獲取相關頻率以及建議關鍵字的屬性。獲取一個不同的實體列表投影到一個新的類型與額外的字段計數

關鍵字類型(EF)具有以下字段:

int Id 
string Text 
string UrlString 

......和許多一對多關係到出版物的實體集。
我快到了。附:

var overlappedKeywords = 
      selectedKeyword.Publications.SelectMany(p => p.Keywords).ToList(); 

在這裏,我得到非常有用的東西:關鍵字的平面化列表,列表中的每個重複出現卻多次與selectedKeyword串聯。

剩下的挑戰:
所以我想每個關鍵字出現在該列表的次數的計數,並投射不同關鍵字實體到一個新的類型,稱爲KeywordCounts,具有相同字段作爲關鍵字,但有一個額外的字段:int PublicationsCount,我將在其中填充overlappedKeywords中的每個關鍵字的計數。 我該怎麼做?

到目前爲止,我已經試過2點的方法:

var keywordCounts = overlappingKeywords 
    .Select(oc => new KeywordCount 
     { 
      KeywordId = oc.Id, 
      Text = oc.Text, 
      UrlString = oc.UrlString, 
      PublicationsCount = overlappingKeywords.Count(ok2 => ok2.Id == oc.Id) 
     }) 
    .Distinct(); 

... PublicationsCount是越來越正確填充,但不同的是不是在這裏工作。 (必須我爲此創建一個EqualityComarer?爲什麼不默認EqualityComarer工作?)

var keywordCounts = overlappingKeywords 
    .GroupBy(o => o.Id) 
    .Select(c => new KeywordCount 
     { 
      Id = ??? 
      Text = ??? 
      UrlString = ??? 
      PublicationsCount = ??? 
     }) 

我不在的GroupBy很清楚。我似乎不具有在選擇「O」的任何訪問,和C不與
我的第一種方法是用傳遞到一個簡單的EqualityComparer工作關鍵字

UPDATE的

任何屬性作曲了。不同的():

class KeywordEqualityComparer : IEqualityComparer<KeywordCount> 
{ 
    public bool Equals(KeywordCount k1, KeywordCount k2) 
    { 
     return k1.KeywordId== k2.KeywordId; 
    } 

    public int GetHashCode(KeywordCount k) 
    { 
     return k.KeywordId.GetHashCode(); 
    } 
} 

......但Slauma的答案是可取的(並接受),因爲它不需要這個。我仍然難以理解EF實體實例的默認EqualityComparer是什麼 - 它不是僅僅根據主要ID進行比較,就像我在上面做的那樣?

+1

我相信EF中應用於投影類型的'Distinct()'(在'Select'之後)將比較投影的結果類型的所有屬性值的相等性。但是在LINQ to Objects(你的代碼實際上是它)中,它會比較對象引用的相等性,這意味着它根本沒有效果,因爲所有對象都是在投影中用new創建的,因此是不同的對象。 – Slauma 2012-04-27 11:56:11

回答

1

第二次嘗試是更好的方法。我認爲,完整的代碼如下:

var keywordCounts = overlappingKeywords 
    .GroupBy(o => o.Id) 
    .Select(c => new KeywordCount 
    { 
     Id = c.Key, 
     Text = c.Select(x => x.Text).FirstOrDefault(), 
     UrlString = c.Select(x => x.UrlString).FirstOrDefault(), 
     PublicationsCount = c.Count() 
    }) 
    .ToList(); 

這是LINQ到對象,我猜,因爲似乎沒有被捲入一個EF上下文,但是對象overlappingKeywords,所以分組發生在內存中,而不是在數據庫。

+0

完整,準確無誤。非常感激。 – Faust 2012-04-27 11:33:26

相關問題