C# LINQ查询中的匹配字符

C# LINQ查询中的匹配字符,c#,asp.net,linq,linq-to-sql,c#-4.0,C#,Asp.net,Linq,Linq To Sql,C# 4.0,我试图在LINQ查询中匹配邮政编码的前5个字符,并使用子字符串来实现这一点。首先,我要检查两个值是否为NULL,这样它就不会从中爆炸出来。这是我正在使用的代码,但我得到一个错误: var lQuery = (from a in gServiceContext.CreateQuery("account") let AccountName = !a.Contains("name") ? string.Empty : a["name"] let Zip = !a.Contains("a

我试图在LINQ查询中匹配邮政编码的前5个字符,并使用子字符串来实现这一点。首先,我要检查两个值是否为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”方法

有没有关于如何绕过这个问题的想法,或者关于更好的方法的建议


谢谢

因此,有些方法在Linq to实体中不受支持,因此您需要将它们放入内存并在那里执行操作:

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将类似于此过于简化的版本:

    Select name... as AccountName, address1_city as City, etc
    From account
所以,若您注意到并没有where子句,那个么将返回表account中的所有行


一些过滤

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
    });

您可以简化一些逻辑。这在我将结果集模拟为一个
IEnumerable
时起作用,因此我猜它将在不知道从gServiceContext.CreateQuery()返回什么类型的情况下处理您的数据:

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


值得注意的是,这不会在服务器上进行任何过滤,会将所有数据带入内存。谢谢!我在账户表中有10000多个账户。有没有可能使它不拖拉整个表?请尝试我的更新,它会将它过滤到一个非常小的子表。您是否可以使用
SqlMethods。例如
在服务器上完全过滤?谢谢!我对第二个版本进行了一次尝试,并获得了“方法'Where'不能跟在方法'Select'后面或不受支持。请尝试使用受支持的方法编写查询,或者在调用不受支持的方法之前调用'AsEnumerable'或'ToList'方法。”有什么想法吗?如果Zip为NULL,它会不会在子字符串上爆炸?
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
                            });
int c = lQuery.Count();