1

我有一个方法,除了一个IEnumerable<T>和一个 lambda 表达式,它描述了用于将 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是 anIEnumerable<string>x.zipcode是 a 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()通过 lambda 传递要在该字段中使用的字段。所以zipCode.zipcode将作为第二个参数传递给方法: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

你忘了(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 回答
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 回答