在任何LINQ到SQL表达式中重用特定属性上的函数



我有以下代码:

var dbContacts = dbContacts.Where(k => k.Name != null && k.Name.ToLower().IndexOf(model.name.ToLower()) > -1);

这显然太长了,我正在努力实现以下功能,而不必在多个属性上重复该功能:

var dbContacts = dbContacts.Where(k => contains(k.Name,model.name));
// or
var dbContacts = dbContacts.Where(k => k.Name.ContainsIgnoreCase(model.name));

我检查了这个线程,所有的答案都使用Expression,它重用整个表达式,而不是特定属性上该表达式中的特定函数。

然而,到目前为止我所尝试的(并且无法翻译LINQ表达式(:

// defining a delegate Func
Func<string, string, bool> contains = (string str, string value) =>
{
return str != null && str.ToLower().IndexOf(value.ToLower()) > -1;
};
// using an extension
public static bool ContainsIgnoreCase(this string str, string value)
{
return str.IndexOf(value, StringComparison.OrdinalIgnoreCase) > -1;
}

我希望在任何LINQ到SQL表达式的特定属性上重用该函数。

有什么想法吗?

据我所知,您正试图创建一个委托函数,用作Linq查询中的过滤器。因此,最后您需要使用您创建的委托Func<string, string, bool>,如下所示:

var dbContacts = dbContacts.Where(k => contains(k.Name,model.name));

这不起作用,因为Where接受Func<T, bool>,所以你需要做这样的事情:

Func<EntityModelClass, bool> contains = (EntityModelClass entity) =>
{
return entity.Name != null && entity.Name.ToLower().IndexOf(entity.Model.ToLower()) > -1;
};

其中CCD_ 5是CCD_。

那么你可以这样做:

var dbContacts = dbContacts.Where(contains);

然而,如果你这样做,你的功能可能会更好:

!string.IsNullOrEmpty(k.Name) && k.Name.IndexOf(model.name, StringComparison.InvariantCultureIgnoreCase) > -1

更新:

根据我在您评论中的理解,您可能正在寻找一个反射解决方案,只需传递属性名称和模型。

这里有一个例子:

public static class LinqExtension
{
public static IEnumerable<T> WhereContains<T>(this IEnumerable<T> source, string propertyName, string model)
{
if(string.IsNullOrEmpty(propertyName)) { throw new ArgumentNullException(nameof(propertyName)); }
if (string.IsNullOrEmpty(model)) { throw new ArgumentNullException(nameof(model)); }
foreach (var item in source)
{
var property = item.GetType().GetProperty(propertyName);
if (property == null)
{
throw new ArgumentNullException(nameof(property));
}
var value = property.GetValue(item, null)?.ToString();
if (!string.IsNullOrEmpty(value) || value.IndexOf(model, StringComparison.InvariantCultureIgnoreCase) > -1)
{
yield return item;
}
}
}
}

那么你的用法是这样的:

var contacts = dbContacts.WhereContains("Name", model.name);

我希望这就是你想要的。

最新更新