在LINQ查询中匹配字符

时间:2011-11-22 19:51:51

标签: c# asp.net linq linq-to-sql c#-4.0

我试图在LINQ查询中匹配Zip代码的前5个字符,我使用SubString来执行此操作。首先,我正在检查是否有任何值为NULL,因此它不会爆炸。这是我正在使用的代码,但是我收到了一个错误:

var lQuery = (from a in gServiceContext.CreateQuery("account")
    let AccountName = !a.Contains("name") ? string.Empty : a["name"]
    let Zip = !a.Contains("address1_postalcode") ? string.Empty : a["address1_postalcode"]
    let State = !a.Contains("address1_stateorprovince") ? string.Empty : a["address1_stateorprovince"]
    let Address = !a.Contains("address1_line1") ? string.Empty : a["address1_line1"]
    let City = !a.Contains("address1_city") ? string.Empty : a["address1_city"]
       where String.IsNullOrEmpty(Zip.ToString()) || String.IsNullOrEmpty(lLead.ZipCode) ? false : Zip.ToString().Substring(0,5).Equals(lLead.ZipCode.Substring(0,5))
       select new
       {
          Name = AccountName
       });
int c = lQuery.ToList().Count();

我得到的错误是:

“方法'Where'不能遵循'Select'方法或不支持。尝试根据支持的方法编写查询,或者在调用不支持的方法之前调用'AsEnumerable'或'ToList'方法。”

有关如何解决这个问题或有关更好方法的建议的任何想法?

谢谢!

2 个答案:

答案 0 :(得分:0)

因此Linq to Entities不支持某些方法,因此您需要将它们放入Memory并在那里执行操作:

var lQuery = (from a in gServiceContext.CreateQuery("account")
    let AccountName = !a.Contains("name") ? string.Empty : a["name"]
    let Zip = !a.Contains("address1_postalcode") ? string.Empty : a["address1_postalcode"]
    let State = !a.Contains("address1_stateorprovince") ? string.Empty : a["address1_stateorprovince"]
    let Address = !a.Contains("address1_line1") ? string.Empty : a["address1_line1"]
    let City = !a.Contains("address1_city") ? string.Empty : a["address1_city"]
    select new 
    {
        AccountName, 
        Zip, 
        State, 
        Address, 
        City, 
        a.lLead
    }).AsEnumerable()
    .Where(i => String.IsNullOrEmpty(i.Zip.ToString()) || String.IsNullOrEmpty(i.lLead.ZipCode) ? false : i.Zip.ToString().Substring(0,5).Equals(i.lLead.ZipCode.Substring(0,5))
    .Select(i => new
    {
        Name = i.AccountName
    });

SQL Generated将看起来像这样过于简化的版本:

    Select name... as AccountName, address1_city as City, etc
    From account

因此,如果您发现没有where子句,则返回表帐户中的所有行。

<小时/> 一些过滤

var lQuery = (from a in gServiceContext.CreateQuery("account")
    let AccountName = !a.Contains("name") ? string.Empty : a["name"]
    let Zip = !a.Contains("address1_postalcode") ? string.Empty : a["address1_postalcode"]
    let State = !a.Contains("address1_stateorprovince") ? string.Empty : a["address1_stateorprovince"]
    let Address = !a.Contains("address1_line1") ? string.Empty : a["address1_line1"]
    let City = !a.Contains("address1_city") ? string.Empty : a["address1_city"]
    where Zip != null 
          && Zip != string.Empty 
          && lLead.ZipCode != null 
          && lLead.ZipCode != string.Empty 
          && Zip.Contains(lLead.ZipCode)
    select new 
    {
        AccountName, 
        Zip, 
        State, 
        Address, 
        City, 
        a.lLead
    }).AsEnumerable()
    .Where(i => i.Zip.ToString().Substring(0,5).Equals(i.lLead.ZipCode.Substring(0,5))
    .Select(i => new
    {
        Name = i.AccountName
    });

答案 1 :(得分:0)

您可以简化一些逻辑。这可以在我的结尾模拟你的结果集IEnumerable<Dictionary<string,string>>,所以我猜它可以使用你的数据,而不知道从gServiceContext.CreateQuery()返回什么类型:

var lQuery = (from a in gServiceContext.CreateQuery("account")
                let AccountName = a.Contains("name") ? a["name"] : String.Empty
                let Zip = a.Contains("address1_postalcode") ? a["address1_postalcode"] : String.Empty
                where  Zip.Substring(0, 5).Equals(lLead.ZipCode.Substring(0, 5))
                select new
                            {
                                Name = AccountName
                            });

您也可以直接在lQuery上调用.Count()。这使得LINQ实现能够选择最有效的方法来计算结果,而不是将整个结果集加载到内存中,并使用LINQ to Objects访问从.ToList()返回的列表的.Count属性。

int c = lQuery.Count();