2013-03-08 69 views
1

我試圖返回一組使用子字符串修剪的獨特結果,但當我調用「Select」時,它會將其轉換爲匿名類型。我似乎無法得到這個維護類型「列表」。我只需要返回Select方法中指定的字段。如何在C#中使用LINQ .Select時保持類型?

public List<Facility> GetFacilities() { 
    var facilities = new List<Facility>(); 
    facilities = _facilityRepository.GetAll().ToList(); 
    var facReturnList = 
     facilities.Where(x => x.Fac_Name = "Something") 
        .OrderBy(x => x.Fac_Name).ToList(); 

    var facReturnList2 = 
     facReturnList.Select(x => 
      new { ID = x.Fac_Name.Substring(0, 6), 
        Fac_Name = x.Fac_Name.Substring(0, 3) }) 
      .Distinct().ToList(); 
    return facReturnList2; 
} 

我試圖new後加入List<Facility>,但它說,這些屬性(IDFac_Name)的設施沒有定義。

+0

您可能會更好地使用Facility的模型而不是返回實體本身。此外,您通常可以通過在查詢之間不使用'.ToList()'來修剪查詢。前兩個linq查詢可能不需要對'ToList'的調用,除非您使用的獨特不可轉換爲sql。 (我們是在談論一個datacontext順便說一句嗎?) – Silvermind 2013-03-08 18:07:14

+0

@Silvermind,認爲你在這兩個帳戶上都是正確的,但我對這種技術是新的,因此我不能肯定地說這是一個「datacontext」 – JamesRLamar 2013-03-08 18:15:24

回答

3

您是否想用結果初始化新的Facility實例?

var facReturnList2 = facReturnList.Select(x => new Facility { ID = // ... 
               ^concrete type initializer 

響應編輯:裏面的Select運營商,你需要指定元素要初始化,不是他們的類型。您之前的代碼似乎表明Fac_NameFacility中定義的,但它顯然不會在List<Facility>中定義。

+0

這就是我所缺少的。我只需要把它作爲一個設施而不是一個列表。謝謝! – JamesRLamar 2013-03-08 18:04:14

+3

你需要*構建它作爲一個設施,而不是投它 – fguchelaar 2013-03-08 18:05:38

+0

@fguchelaar,我覺得這個術語是不正確的。我一定會考慮的。 – JamesRLamar 2013-03-08 18:14:01

2

您正在創建一個匿名類型,因爲您正在創建它。

.Select(x => new { 

如果你不想這樣做,不要這樣做。

如果現有類型已經具有您需要的名稱和確切的屬性,請使用它。如果沒有你需要的類型,創建一個。然後您可以返回該類型的適當列表或枚舉類型。

.Select(x => new YourDefinedType { 
1

下面的代碼是指示LINQ返回一個匿名類型:

.Select(x => new { ID = x.Fac_Name.Substring(0, 6), Fac_Name = x.Fac_Name.Substring(0, 3) } 

你需要創建一個類你的結果

public class Result{ 
    public string ID { get;set; } 
    public string Fac_Name { get; set; } 
} 

//Then do 

.Select(x => new Result { ID = x.Fac_Name.Substring(0, 6), Fac_Name = x.Fac_Name.Substring(0, 3) } 

這將確保你只返回你需要

信息
2

這聽起來像你真正想要的是一個DistinctBy方法。你想要指定一些方法來指示一個對象是不同的,但你不希望結果是該選擇的集合,你希望最終的結果成爲起始對象。 LINQ沒有DistinctBy內置的,但實現一個是很容易的:

public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer = null) 
{ 
    comparer = comparer ?? EqualityComparer<TKey>.Default; 
    HashSet<TKey> knownKeys = new HashSet<TKey>(comparer); 
    foreach (TSource element in source) 
    { 
     if (knownKeys.Add(keySelector(element))) 
     { 
      yield return element; 
     } 
    } 
} 

使用你的代碼現在可以變爲:

public List<Facility> GetFacilities() 
{ 
    return _facilityRepository.GetAll() 
     .Where(x => x.Fac_Name == "Something") 
     .DistinctBy(x => new 
     { 
      ID = x.Fac_Name.Substring(0, 6), 
      Fac_Name = x.Fac_Name.Substring(0, 3) 
     }) 
     .OrderBy(x => x.Fac_Name) 
     .ToList(); 
} 

在你有一個IQueryable在內存而不是一個事件數據集,您可以使用GroupBy來獲得相同的行爲。在使用GroupBy的Linq-to-objects中效率會低很多,但對於查詢提供者而言,它不會像數據庫能夠優化這一點。

public List<Facility> GetFacilities() 
{ 
    return _facilityRepository.GetAll() 
     .Where(x => x.Fac_Name == "Something") 
     .OrderBy(x => x.Fac_Name) 
     .GroupBy(x => new 
     { 
      ID = x.Fac_Name.Substring(0, 6), 
      Fac_Name = x.Fac_Name.Substring(0, 3) 
     }) 
     .Select(group => group.First()) 
     .ToList(); 
} 
+0

我仍然沒有得到明顯的結果,並且使用您的代碼「DistinctBy」不是公認的擴展方法。我將在這裏創建關於這個問題的另一個問題,http://stackoverflow.com/questions/15301068/how-to-get-a-distinct-result-using-linq-and-c-sharp-using-method-syntax。我認爲你的答案和這一個可能是在正確的軌道,http://stackoverflow.com/questions/8853390/select-distinct-from-datatable-using-linq-and-c-sharp – JamesRLamar 2013-03-08 18:44:00

+0

@JamesRLamar我提供了定義在這篇文章中的擴展方法。正如我所說,它不在LINQ本身。 – Servy 2013-03-08 18:48:23

+0

我得到了你。我像你所建議的那樣爲它添加了靜態類。在後臺我有一些其他的東西來獲取存儲庫,所以我猜這就是衝突可能發生的地方。我非常感謝你的幫助。 – JamesRLamar 2013-03-08 20:18:43

相關問題