gpt4 book ai didi

c# - 我可以使以下 IQueryable linq 语句通用吗

转载 作者:行者123 更新时间:2023-11-30 15:36:58 24 4
gpt4 key购买 nike

有没有办法让下面的数据库查询生成器通用?

private IQueryable<Foo> ByName(IQueryable<Foo> dbQuery, Query query)
{
string[] searchTerms = query.Data.Replace(" ","").ToLower().Split(',');

if (query.Exclude)
{
return dbQuery.Where(x => searchTerms.All(
y => y != x.Name.Replace(" ", "").ToLower()));
}

return dbQuery.Where(x => searchTerms.Any(
y => y == x.Name.Replace(" ", "").ToLower()));
}

对于 Foo 的许多不同属性,我已经得到了相同的函数。按县、按镇、按街道等

我写过一些像下面这样返回 linq 的函数

public Expression<Func<Foo, bool>> FoosAreWithinDistanceFromGeocode(
double distance, Geocode geocode)
{
double distanceSquare = distance * distance;
return foo => ( SqlFunctions.Square((double)(
foo.Address.Geocode.Easting - geocode.Easting)) +
SqlFunctions.Square((double)(fooAddress.Geocode.Northing -
geocode.Northing)) ) <= distanceSquare;
}

但我似乎找不到 Linq-to-SQL 的东西是否不能使用泛型,或者是否可以将属性作为泛型传递等等。


编辑:我一般针对单个搜索词使用此功能。

Where [query.Data == "Foo1"]

return dbQuery.Where(SearchMatch("Name", query.Data));

public Expression<Func<Foo, bool>> SearchMatch(string propertyName, string searchTerm)
{
var foo = Expression.Parameter(typeof(Foo), "foo");
var prop = Expression.Property(foo, propertyName);
var search = Expression.Constant(searchTerm);
var equal = Expression.Equal(prop, search);

return Expression.Lambda<Func<Foo, bool>>(equal, foo);
}

有人知道如何让它适用于字符串数组吗?

最佳答案

您需要定义一个接口(interface)来公开您要访问的属性,如下所示:

public interface IHaveName
{
string Name { get; }
}

然后,在您的类中,您将实现接口(interface):

public class Foo : IHaveName

如果您使用的是从 DBML 文件生成的类,这些类将标有 partial keyword所以实现接口(interface)就像创建一个新文件一样简单,然后插入:

public partial class Foo : IHaveName

由于该属性已在从 .dbml 文件生成的其他 .cs 文件中声明为公共(public),因此该接口(interface)是隐式实现的。

最后,您将重写您的 ByName 方法以获取一个泛型类型参数,并带有实现您的接口(interface) IHaveName 的约束:

private IQueryable<T> ByName<T>(IQueryable<T> dbQuery, Query query)
where T : IHaveName
{
// Everything else is the same.

对于您的其他属性(以及使用它们的方法),您可以将它们聚合到一个接口(interface)中,或将它们分开,具体取决于您的需要。


根据您的编辑,如果您想动态创建一个表达式,您不必放弃编译时安全:

public Expression<Func<Foo, bool>> SearchMatch(
Expression<Func<Foo, string>> property, string searchTerm)
{
var foo = Expression.Parameter(typeof(Foo), "foo");
// Get the property info from the property expression.
var prop = Expression.Property(foo,
(property.Body as MemberExpression).Member as PropertyInfo);
var search = Expression.Constant(searchTerm);
var equal = Expression.Equal(prop, search);

return Expression.Lambda<Func<Foo, bool>>(equal, foo);
}

然后你可以这样调用:

var expression = SearchMatch(f => f.Name, "searchTerm");

这确保您传递给 SearchMatch 的属性确实存在于 Foo 上。请注意,如果您想为其他标量属性类型制作此泛型,您将执行以下操作:

public Expression<Func<Foo, bool>> SearchMatch<T>(
Expression<Func<Foo, T>> property, T searchTerm)
{
var foo = Expression.Parameter(typeof(Foo), "foo");
// Get the property info from the property expression.
var prop = Expression.Property(foo,
(property.Body as MemberExpression).Member as PropertyInfo);
var search = Expression.Constant(searchTerm);
var equal = Expression.Equal(prop, search);

return Expression.Lambda<Func<Foo, bool>>(equal, foo);
}

关于c# - 我可以使以下 IQueryable linq 语句通用吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13180227/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com