我有以下代码。
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 to 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;
};
其中 EntityModelClass
是 dbContacts
实体。
那么你可以这样做。
var dbContacts = dbContacts.Where(contains);
然而,如果你这样做,你的功能可能会更好。
!string.IsNullOrEmpty(k.Name) && k.Name.IndexOf(model.name, StringComparison.InvariantCultureIgnoreCase) > -1
UPDATE :
根据我在你的评论中的理解,你可能正在寻找一个反射解决方案,在那里你只需要传递属性名称和模型。
这里有一个例子。
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);
我希望这就是你要找的东西。