C# 将函数或扩展方法与linq组合以匹配别名时出现的问题
在一个数据库中,我从几个别名中获取数据,这些别名用于一个ID(catch-all-ID),而这个ID需要与之进行比较的值也是如此。然而,Linq不允许我使用扩展或函数来选择记录,或者我在这里做了一些错误的事情 假设null、“”和“Default”是Catch All ID的可能值,其中任何其他值都应视为单独的值 我正在寻找一种方法来生成一个linq select,它以一种干净且可维护的方式匹配别名 似乎有效的方法是:C# 将函数或扩展方法与linq组合以匹配别名时出现的问题,c#,asp.net-mvc-3,linq-to-sql,C#,Asp.net Mvc 3,Linq To Sql,在一个数据库中,我从几个别名中获取数据,这些别名用于一个ID(catch-all-ID),而这个ID需要与之进行比较的值也是如此。然而,Linq不允许我使用扩展或函数来选择记录,或者我在这里做了一些错误的事情 假设null、“”和“Default”是Catch All ID的可能值,其中任何其他值都应视为单独的值 我正在寻找一种方法来生成一个linq select,它以一种干净且可维护的方式匹配别名 似乎有效的方法是: using (DataContext context = new DataC
using (DataContext context = new DataContext())
{
var q = (from c in context.BasketContents
where
(c.ID+" ").Replace("Default", "").Replace("_", "")
==
(Value+" ").Replace("Default", "").Replace("_", "")
select c);
}
或者,这也适用于:
where ((c.ID==null |c.ID=="Default" | c.ID=="_" | c.ID=="") &
(Value==null |Value=="Default" | Value=="_" | Value=="")) |
(c.ID==Value))
更糟糕的是:)
由于需要在大量查询中进行此比较,我希望使用扩展或函数,因此我尝试结合以下内容:
private bool IsSameID(string a1, string a2)
{
return ((a1 == null | a1 == "Default" | a1 == "_" | a1 == "")
&& (a2 == null | a2 == "Default" | a2 == "" | a2 == "_"))
| (a1 == a2) ? true : false;
}
对于查询:
using (DataContext context = new DataContext())
{
var q = (from c in context.BasketContents
where
IsSameID(c.ID,Value)
select c);
}
这会引发以下异常:布尔值“IsSameID(System.String,System.String)”不支持到SQL的转换
我还编写了一个扩展方法,可以处理以下替换:
public static string DeAlias(this string a)
{
return (a == null | a == "Default" | a == "_" | a == "") ? "" : a;
}
因此我可以比较ID.DeAlias()==Value.DeAlias()
,但这基本上有相同的问题
那么我做错了什么呢?LINQ to SQL无法将自定义方法转换为SQL。您应该在客户端过滤篮子内容:
from c in context.BasketContents.AsEnumerable()
where IsSameID(c.ID,Value)
select c
或者不使用自定义方法
from c in context.BasketContents
where (c.ID == null || c.ID == "Default" || c.ID == "_" || c.ID == "") &&
c.ID == Value
select c
正如我在注释中指出的,如果您想从查询中提取复杂的筛选,您还可以创建返回类型为expression
的表达式的方法:
private Expression<Func<BasketContents,bool>> IsSameID(string value)
{
return (Expression<Func<BasketContents,bool>>)(c =>
((c.ID == null || c.ID == "Default" || c.ID == "_" || c.ID == "") &&
c.ID == value);
}
LINQ to SQL无法将自定义方法转换为SQL。您应该在客户端过滤篮子内容:
from c in context.BasketContents.AsEnumerable()
where IsSameID(c.ID,Value)
select c
或者不使用自定义方法
from c in context.BasketContents
where (c.ID == null || c.ID == "Default" || c.ID == "_" || c.ID == "") &&
c.ID == Value
select c
正如我在注释中指出的,如果您想从查询中提取复杂的筛选,您还可以创建返回类型为expression
的表达式的方法:
private Expression<Func<BasketContents,bool>> IsSameID(string value)
{
return (Expression<Func<BasketContents,bool>>)(c =>
((c.ID == null || c.ID == "Default" || c.ID == "_" || c.ID == "") &&
c.ID == value);
}
真的没有办法让linq超负荷吗?那太令人失望了。人们希望这是可能的,因为您还可以执行类似.ToString()的操作?是什么使linq能够转换为SQL,还是能够实现SQL重载?@davidegman有一组方法,可以由linq转换(例如,集合
包含方法在查询中转换为SQL),但任何方式都不支持自定义方法。如果您想让查询更可读,请考虑创建返回代码< >表达式< /代码>的方法,并调用此方法<代码>(您的方法返回表达式)<代码>谢谢,仍然令人失望,但至少是决定性的。如果我有足够的声誉,我会投票支持你的答案:)也许你能给出这样一个表达方法的线索吗?@GertArnold刚刚接受了它。拉兹别列佐夫斯基:谢谢!我想知道我对拉兹别列佐夫斯基的答案所做的编辑到底发生了什么?这些都是错的吗?(无论如何,我很快就会在实时代码中发现这一点)真的没有办法让linq过载吗?那太令人失望了。人们希望这是可能的,因为您还可以执行类似.ToString()的操作?是什么使linq能够转换为SQL,还是能够实现SQL重载?@davidegman有一组方法,可以由linq转换(例如,集合包含方法在查询中转换为SQL),但任何方式都不支持自定义方法。如果您想让查询更可读,请考虑创建返回代码< >表达式< /代码>的方法,并调用此方法<代码>(您的方法返回表达式)<代码>谢谢,仍然令人失望,但至少是决定性的。如果我有足够的声誉,我会投票支持你的答案:)也许你能给出这样一个表达方法的线索吗?@GertArnold刚刚接受了它。拉兹别列佐夫斯基:谢谢!我想知道我对拉兹别列佐夫斯基的答案所做的编辑到底发生了什么?这些都是错的吗?(无论如何,我很快就会在实时代码中发现这一点)