Как написать динамическое выражение выбора - PullRequest
0 голосов
/ 12 апреля 2019

Мне нужно написать какое-нибудь динамическое выражение выбора в структуре сущностей, как в примере.

var list = db.Article
    .GroupBy(x => x.CategoryId)
    .Select(x => new ArtDto
    {
        No = x.Select(c => c.NUMBER).FirstOrDefault(),
        UserName = x.Key,
        Count = x.Count()
    })
    .ToList();

Я могу написать группу с таким выражением:

Expression<Func<Article, int>> groupByExp;
groupByExp = (x) => x.CategoryId;

Так что я могу заменить фактическое выражение на groupByExp.

var list = db.Article
    .GroupBy(groupByExp)
    .Select(x => new ArtDto
    {
        No = x.Select(c => c.NUMBER).FirstOrDefault(),
        UserName = x.Key,
        Count = x.Count()
    })
    .ToList();

Я также хочу написать другое выражение для выбора. Поэтому я могу отправить его в другую функцию, и она будет динамической в ​​этой функции.

Expression<Func<Article, bool>> selectExp;
selectExp = (x) => new ArtDto { ... };

Возможно ли это? У вас есть идея или учебник для этого?

Ответы [ 2 ]

2 голосов
/ 12 апреля 2019

Да, это возможно,

перед запуском вам необходимо:

  • Создать новый объект для выбранных свойств
  • Сопоставить вашу модель с новым объектом

давайте рассмотрим, что у вас есть ваша модель Article, и вам нужно вернуть новую модель ArticleSummary, как показано ниже

public class Article {
 public int id { get; set; }
 public string Title { get; set; }
 public string Introduction { get; set; }
 public string AuthorId { get; set; }
 public AppUser Author { get; set; }
 public DateTime PublishDate { get; set; }
}

public class ArticleSummary {
 public int Id { get; set; }
 public string Title { get; set; }
 public string Introduction { get; set; }
}

, и вот отображение:

Expression<Func<Article, ArticleSummary>> mapArticle = x => new ArticleSummary {
    Id = x.Id,
    Title = x.Title,
    Introduction = x.Introduction
};

и вот «упрощенная» функция данных:

// T is Article model
// U is ArticleSummary model
public async Task<ICollection<U>> SelectListAsync<T, U>(
            Expression<Func<T, bool>> search,
            Expression<Func<T, U>> select) where T : class
{
    var query =
    _context.Set<T>()
    .Where(search)
    .Select(select);

    return await query.ToListAsync();
}

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

1 голос
/ 12 апреля 2019

Ваше выражение должно принимать IIGrouping<T, Article> в качестве первого аргумента (где T - это тип CategoryId). Предполагая, что CategoryId равен int выражение может быть записано как

public static Expression<Func<IGrouping<int, Article>, ArtDto>> SelectExpression()
{
    return x => new ArtDto
    {
        No = x.Select(c => c.NUMBER).FirstOrDefault(),
        UserName = x.Key,
        Count = x.Count()
    };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...