1

IEnumerable<T>および linq-to-sql コレクションを配列と比較するために使用されるフィールドを記述するラムダ式を除くメソッドがあります。このメソッドは、一致するレコードを返します。

public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, 
        Func<ZipCode, T> matchPhrase) {
    return (from zipCode in _table
            where values.Contains<T>(matchPhrase)
            select zipCode).Distinct();
}

エラーが発生します:

引数の型'Func<ZipCode, T>'はパラメーターの型に割り当てられません'T'

メソッドは次のように呼び出されます (ここvaluesで、 は でありIEnumerable<string>x.zipcodeは ですstring)。

var zipCodes = _zipCodeRepository.match(values, x => x.zipcode)

アップデート

ジョンの使用の提案に基づいてHashSet<T>、コードを変更しましたが、別のエラーが発生しています

メソッド 'System.Object DynamicInvoke(System.Object[])' には、サポートされている SQL への変換がありません。

私の質問が明確ではなかったと思います。目的の結果を得るために間違ったメソッド シグネチャを使用していると思います。より簡単なコード例で説明しましょう。

public IEnumerable<ZipCode> match(IEnumerable<string> values) {
    return (from zipCode in _table
            where values.Contains(zipCode.zipcode)
            select zipCode).Distinct();
}

私はこれを達成するのに苦労していますが、匿名型を使用しています。Contains()ラムダ経由で使用するフィールドを渡したいと思います。したがってzipCode.zipcode、2 番目の引数としてメソッドに渡されます。x => x.zipcode

4

3 に答える 3

2

私はあなたが代表者に電話したかったと思います:

return (from zipCode in _table
        where values.Contains(matchPhrase(zipCode))
        select zipCode).Distinct();

気をつけてください、それは潜在的に非常に高価になるでしょう。最初にセットを作成することをお勧めします。

HashSet<T> valueSet = new HashSet<T>(values);
return _table.Where(x => valueSet.Contains(matchPhrase(x))
             .Distinct();

(ここでは、読みやすさの点で良いというよりも害を及ぼしていたため、クエリ式を削除しました。)

于 2013-02-04T19:53:32.223 に答える
1

は、式ではなく、引数として文字列のみを受け入れます。このレベルでパラメータ化することはできません。

where部分をパラメータとして全体に渡すことができます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace ConsoleApplication
{
    class Program
    {
         static void Main(string[] args)
         {
             var values = new List<string>();
             values.Add("123");

             Console.WriteLine(
                 Match(zip => values.Contains(zip.Code)).Count()); // -> 1

             Console.WriteLine(
                 Match(zip => values.Contains(zip.OtherCode)).Count()); // -> 0

             Console.Read();
         }

         public static IEnumerable<ZipCode> Match(Expression<Func<ZipCode, bool>> predicate)
         {
             var table = new List<ZipCode> 
                      { new ZipCode { Code = "123" }, new ZipCode { OtherCode = "234" } }
                .AsQueryable();

             return (from zipCode in table.Where(predicate)
                    select zipCode).Distinct();
         }
     }
     public class ZipCode
     {
         public string Code { get; set; }

         public string OtherCode { get; set; }
     }
}
于 2013-02-04T20:59:24.903 に答える
1

入れ忘れ(zipCode)Contains

public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, Func<ZipCode, T> matchPhrase) {
    return (from zipCode in _table
            where values.Contains(matchPhrase(zipCode))  // <- Here (and you don't need to specify <T>, the compiler deduce it from the argument)
            select zipCode).Distinct();
}

Join メソッドを使用してパフォーマンスを向上させることができます (複雑さは のO(n)とおりです)。

public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, Func<ZipCode, T> matchPhrase)
{
    return (from zipCode in _table
            join value in values on matchPhrase(zipCode) equals value
            select zipCode).Distinct();
}
于 2013-02-04T19:52:59.653 に答える