情境:
当列FooTable
为Foo
时,我有一个表varchar(8) NOT NULL
,此列中的信息如下:
Foo
-----------
13940-00
13940-01
13940-02
13941-00
13941-01
连字符后面的数字部分(-
)总是有两位数。
问题:
我正在使用Ado.net Entity Framework,我创建了一个包含2个静态方法的类来帮助获取数字的第一和第二部分:
public class HelperFoo
{
public static string Prefix(string value) { /* code here */ }
public static string Suffix(string value) { /* code here */ }
}
所以现在我可以这样做:
context.FooTable.Where(w => HelperFoo.Prefix(w.Foo) == "13940");
但是,正如您可能已经知道的那样,此命令行会抛出NotSupportedException
。这是因为LINQ无法识别HelperFoo.Prefix
,因此无法在SQL中转换表达式。
我可以在SQL中编写一个与HelperFoo
方法相同的代码块,这样我就可以为我的方法创建SQL。
问题
我可以创建一些东西(类,方法或其他),使LINQ在执行LINQ代码时知道我的方法吗?
EDITED
PS :我需要一些类似于方法或SQL函数的泛型,因为我需要在Select,OrderBy,GroupBy和其他许多场景中获得此前缀和后缀。
答案 0 :(得分:2)
你可以尝试为FooTable创建自己的IQueryable
过滤器,有点像这样:
public static class Filters
{
public static IQueryable<FooTable> WithPrefix(this IQueryable<FooTable> item, string prefix)
{
return item.Where(i => i.Foo.StartsWith(prefix));
// note that this should be the same code you have in the
// Prefix() method inside HelperFoo...
}
}
您可以这样使用:
context.FooTable.WithPrefix("13940");
更新:遗憾的是,此处的第二个选项不起作用:
另一个选择是让帮助方法不为Predicate<>
返回值FooTable
:
public class HelperFoo
{
public static Func<FooTable, bool> Prefix(string value)
{
return (i) => i.Foo.Substring(0, 5) == value;
}
public static Func<FooTable, bool> Suffix(string value) { /* code here */ }
}
并像这样使用它:
context.FooTable.Where(HelperFoo.Prefix("13940"));
警告:我不完全确定第二种方法不会给你带来同样的问题。
答案 1 :(得分:2)
使用芒果的plethera,你说它需要更通用,你需要前缀和后缀可用Select
,OrderBy
,&amp; GroupBy
个关键字,您应该在两个不同的字段中包含前缀和后缀。
Foo Table
----------
Prefix | Suffix
----------------
10245 | 05
通过它,您可以单独查询它们以获得您想要的内容:
var resultSet = Db.Foo.Where(x => x.Suffix == "05").OrderBy(x => x.Prefix);
使用此功能,您可以轻松添加只读属性以获取格式化值:
public [partial] class Foo {
//Your other code
public string FormattedValue {
get { return Prefix + "-" + Suffix; }
}
}
答案 2 :(得分:1)
您可以使用.StartsWith
检查前缀:
string prefix = "13940";
var result = context.FooTable.Where(w => w.Foo.StartsWith(prefix + "-"));
和.EndsWith
检查后缀:
string suffix = "02";
var result = context.FooTable.Where(w => w.Foo.EndsWith("-" + suffix));
答案 3 :(得分:0)
您可以在Foo类中创建自定义getter:
public class Foo
{
//your code
[NotMapped]
public string Prefix { get { return /*whatever*/; }
}
我认为这应该有用。
答案 4 :(得分:0)
您无法根据自定义函数过滤数据库选择 - 正如您所说,它无法将其转换为SQL。
对于这个特定问题,我建议你使用StartsWith函数,它可以在SQL服务器上运行
context.FooTable.Where(w => w.Foo.StartsWith("13940"));
答案 5 :(得分:0)
使用Microsoft.Linq.Translations
。
它看起来像这样:
partial class FooTable
{
private static readonly CompiledExpression<FooTable,string> prefixExpression
= DefaultTranslationOf<FooTable>.Property(e => e.Prefix).Is(e => e.Foo.Substring(0, 5));
public string Prefix
{
get { return prefixExpression.Evaluate(this); }
}
}
并且询问:
context.FooTable.Where(w => w.Prefix == "13940").WithTranslations();
编辑:此解决方案适用于Select,GroupBy,OrderBy。