在任何LINQ to SQL表达式中重用一个特定属性的函数。

问题描述 投票:1回答:1

我有以下代码。

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表达式中重用特定属性的函数。

有什么想法吗?

c# linq-to-sql ef-core-2.0
1个回答
0
投票

根据我的理解,你是想创建一个委托函数,作为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;
};

其中 EntityModelClassdbContacts 实体。

那么你可以这样做。

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);

我希望这就是你要找的东西。

© www.soinside.com 2019 - 2024. All rights reserved.