Повторно использовать функцию для указанного свойства c в любом выражении LINQ to SQL - PullRequest
1 голос
/ 27 апреля 2020

У меня есть следующий код:

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, где вместо этого используется целое выражение вместо указанной c функции в этом выражении для указанного свойства c.

Однако то, что я пробовал до сих пор (и получение выражения 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;
}

Я хотел бы повторно использовать эту функцию для указанного свойства c в любом выражении LINQ to SQL .

Есть идеи?

1 Ответ

0 голосов
/ 27 апреля 2020

Из того, что я понял, вы пытаетесь создать функцию делегата, которая будет использоваться в качестве фильтра в запросах Linq. поэтому в конце вам нужно использовать созданный вами делегат Func<string, string, bool> следующим образом:

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

это не будет работать, потому что Where принимает Func<T, bool>, поэтому вам нужно сделать что-то вроде this:

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

ОБНОВЛЕНИЕ:

Из того, что я понял в ваших комментариях, вы, вероятно, ищете решение для отражения, в котором вы просто передаете имя свойства и модель.

вот пример:

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

Я надеюсь, что это то, что вы ищете.

...