簡體   English   中英

LINQ查詢和字符串數組

[英]LINQ query and Array of string

我有一個string數組說:

String[] Fields=new String[]{RowField,RowField1}

我可以在其中使用以下查詢通過指定查詢的值(即RowFieldRowField1來獲取值:

var Result = (
    from x in _dataTable.AsEnumerable()
    select new
    {
        Name = x.Field<object>(RowField), 
        Name1 = x.Field<object>(RowField1)
    })
    .Distinct();

但是如果假設我在Array有很多值,例如:

String[] Fields= new String[]
{
    RowField,
    RowField1,
    RowField2,
    .......
    RowField1000
};
  • 如何在不指定查詢中每個行字段的情況下在此處使用查詢?
  • 我如何遍歷LINQ中的數組項?
var Result = (
    from x in _dataTable.AsEnumerable()
    select (
        from y in Fields
        select new KeyValuePair<string, object>(y, x))
        .ToDictionary())
    .Distinct(DictionariesComparer);

您還需要編寫自己的.ToDictionary()擴展方法和DictionariesComparer方法(因為Dictionary不實現IEquatable )。

本質上,您想從數據表中檢索特定字段,而無需對字段名進行硬編碼。

以下代碼將每行返回一個字典對象,其中包含您在數組中指定的字段。 無需創建其他擴展方法或比較器:

var result = (from row in _dataTable.AsEnumerable()
                 let projection = from fieldName in fields
                      select new {Name = fieldName, Value = row[fieldName]}
                 select projection.ToDictionary(p=>p.Name,p=>p.Value));            

內部選擇從每個表行中選擇您需要的字段值,並將它們存儲在投影變量中。 外部選擇將此變量轉換為Dictionary

您可以遍歷結果以獲取特定字段,如下所示:

foreach (var row in result)
{
    Console.WriteLine(row["field1"]);
}

編輯:上面的代碼不會返回不同的值。 無需使用group by編寫特殊的比較器就可以返回不同的值但是代碼不是很漂亮:

var result = (from row in table.AsEnumerable()
                let projection = from fieldName in fields
                                select new { Name = fieldName, Value = row[fieldName] }
                group projection by projection.Aggregate((v, p) =>
                    new {
                        Name = v.Name + p.Name, 
                        Value = (object)String.Format("{0}{1}", v.Value, p.Value)
                    }) into g
                select g.FirstOrDefault().ToDictionary(p=>p.Name,p=>p.Value));  

聚合將創建一個新的投影,其名稱和值屬性是所有名稱和值字段的串聯。 聚合的結果用於對所有行進行分組,並返回每組的第一行。 它有效,但是絕對難看。

最好像下面的代碼那樣創建一個簡單的DictionaryComparer:

    public class DictionaryComparer<TKey,TValue>: EqualityComparer<Dictionary<TKey,TValue>>
    {
        public override bool Equals(Dictionary<TKey, TValue> x, Dictionary<TKey, TValue> y)
        {
            //True if both sequences of KeyValuePair items are equal
            var sequenceEqual = x.SequenceEqual(y);
            return sequenceEqual;
        }

        public override int GetHashCode(Dictionary<TKey, TValue> obj)
        {
            //Quickly detect differences in size, defer to Equals for dictionaries 
            //with matching sizes
            return obj.Count;
        }
    }

這使您可以編寫:

        var result = (from row in table.AsEnumerable()
                     let projection = from fieldName in fields
                                      select new {Name = fieldName, Value = row[fieldName]}                                                                                    
                     select projection.ToDictionary(p=>p.Name,p=>p.Value))
                     .Distinct(new DictionaryComparer<string, object>());

沒有foreach linq表達式。 我通常創建自己的擴展方法

類似於以下內容:

public static void Foreach<T>(this IEnumerable<T> items, Action<T> action)
{
 foreach(T t in items)
 {
  action(t);
 }
}

但是請注意,如果您打算將它與Linq2SQL一起使用,因為它可能會產生很多數據庫匹配!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM