Создайте динамическую c функцию выбора в Enity Framework - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть вопрос к вам относительно создания запроса выбора Dynami c в Entity Framework. У меня уже есть динамический запрос c для выбора на основе прав и т. Д. c. Но для каждой таблицы я получаю более 30 полей, которые мне нужно проанализировать с помощью .GetType (). GetProperties (). Это сложный и довольно дорогой ресурс с точки зрения количества данных, которые мы имеем. У меня есть служба, которая сообщает мне, какие поля я должен выбрать для каждой таблицы. Я хотел бы найти способ преобразовать это в запрос, но я не могу найти что-то действительно динамическое c. То есть не Dynami c, а руководство :

using (var context = new StackOverflowContext())
{
    var posts = context.Posts
                       .Where(p => p.Tags == "<sql-server>")
                       .Select(p => new {p.Id, p.Title});

    // Do something;
} 

Я должен сказать, выберите только эти поля, но только поля с этими именами. У меня есть список полей в списке строк, но это можно изменить.

Не могли бы вы мне помочь?

1 Ответ

1 голос
/ 03 апреля 2020

Вот код. Net Fiddle (сделан msbendtsen), который позволяет динамически выбирать столбцы (свойства). https://dotnetfiddle.net/3IMR1r Пример написан для linq к объектам, но он должен работать с каркасами сущностей.

Раздел ключа:

internal static IQueryable SelectProperties<T>(this IQueryable<T> queryable, IEnumerable<string> propertyNames)
{
    // get propertyinfo's from original type
    var properties = typeof(T).GetProperties().Where(p => propertyNames.Contains(p.Name));

    // Create the x => expression
    var lambdaParameterExpression = Expression.Parameter(typeof(T));
    // Create the x.<propertyName>'s
    var propertyExpressions = properties.Select(p => Expression.Property(lambdaParameterExpression, p));

    // Creating anonymous type using dictionary of property name and property type
    var anonymousType = AnonymousTypeUtils.CreateType(properties.ToDictionary(p => p.Name, p => p.PropertyType));
    var anonymousTypeConstructor = anonymousType.GetConstructors().Single();
    var anonymousTypeMembers = anonymousType.GetProperties().Cast<MemberInfo>().ToArray();

    // Create the new {} expression using 
    var anonymousTypeNewExpression = Expression.New(anonymousTypeConstructor, propertyExpressions, anonymousTypeMembers);

    var selectLambdaMethod = GetExpressionLambdaMethod(lambdaParameterExpression.Type, anonymousType);
    var selectBodyLambdaParameters = new object[] { anonymousTypeNewExpression, new[] { lambdaParameterExpression } };
    var selectBodyLambdaExpression = (LambdaExpression)selectLambdaMethod.Invoke(null, selectBodyLambdaParameters);

    var selectMethod = GetQueryableSelectMethod(typeof(T), anonymousType);
    var selectedQueryable = selectMethod.Invoke(null, new object[] { queryable, selectBodyLambdaExpression }) as IQueryable;
    return selectedQueryable;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...