Entity Framework Core - извлекает все столбцы, кроме нескольких, в общем случае c - PullRequest
0 голосов
/ 11 марта 2020

Интересно, есть ли лучшее решение для моей проблемы, чем это https://entityframeworkcore.com/knowledge-base/44877455/get-all-columns-except-one-in-efcore

У меня есть несколько моделей со многими столбцами (скажем, 20), и несколько столбцов тяжелые - сгустки. Естественно, я хотел бы иметь метод извлечения данных (список из них) легким способом - т.е. исключая эти несколько столбцов. До сих пор единственный работающий метод - тот, который предложен в ссылке выше, то есть

оригинальная модель:

{
    public Rating() { }
    public int IdRating { get; private set; }
    public string IdUser { get; set; }
    public decimal Value { get; private set; }
    public string Comment { get; private set; }
    public bool IsEnabled { get; set; }
    public int IdCorrespondent { get; private set; }}

, затем более легкая версия

public class RatingView
{
    public Rating() { }
    public int IdRating { get; private set; }
    public decimal Value { get; private set; }
}

и данные Извлечение -

public List<RatingView> ListRatings()
    {
        return _context.Ratings.Select(x => new RatingView
        {
            IdRating = x.IdRating ,
            Value = x.Value ,
        }).ToList();

    }

. Первая проблема состоит в том, что слишком много столбцов, чтобы установить этот путь, и, во-вторых, есть несколько похожих классов, поэтому решение не очень хорошее и подвержено ошибкам для будущих изменений моделей. Automapper выглядит неплохо, но сгенерированные запросы не оптимальны - все столбцы получены.

Спасибо, arbus

1 Ответ

0 голосов
/ 12 марта 2020

Просматривая другие сообщения stackoverflow и пользуясь помощью нескольких людей, я нашел 5 решений, для которых первое из них является лучшим для меня - благодарность Lucian Bargaoanu

1) на основе Automapper

http://docs.automapper.org/en/latest/Queryable-Extensions.html#explicit - расширение
На самом деле, нет даже необходимости создавать отдельный класс освещения с ограниченным числом полей - Automapper может игнорировать тяжелые поля и сгенерированный запрос SQL не будут их использовать.

var ratings = _db.Ratings.Where(...).ProjectTo<Rating>(new MapperConfiguration
    (cfg => { cfg.CreateMap<Rating, Rating>()
        .ForMember(d => d.Comment, m => m.Ignore())
        .ForMember(d1 => d1.IdUser, m1 => m1.Ignore()); })).ToList();

Если вы хотите использовать класс Light, такой как RatingView, - просто сопоставьте его, не игнорируя ничего.

2 ) Проектирование базы данных При проектировании таблицы не включайте эти тяжелые столбцы в таблицу, а вместо этого - создавайте представление, если вам нужно все в одной модели. К сожалению, если вы наследуете таблицу, это не вариант

3) EF Core Разделение таблицы (предложено Crypt32) Можно выполнить разбиение таблицы с использованием механизма EF Core

https://docs.microsoft.com/en-us/ef/core/modeling/table-splitting это также объяснено здесь EFCore Map 2 сущности в одну и ту же таблицу

Я думаю, что это возможно из базовой версии 3 EF, которая на момент написания статьи не доступен для меня, так как я использую ядро ​​EF с Oracle. Нет необходимости в представлениях в базе данных, нет необходимости отображать и перечислять все свойства, но все же есть необходимость создавать эти классы моделей освещения.

4) Исходное решение который также работает. https://entityframeworkcore.com/knowledge-base/44877455/get-all-columns-except-one-in-efcore
Как уже упоминалось ранее, недостатком является необходимость создания множества легких классов и написания громоздкого кода со многими свойствами, а затем поддержка всех этих сущностей в ходе эволюции вашего решения.

Кевин Доккс посоветовал две другие возможности, которые оба очень хороши.

5) Просмотр создания и сопоставление класса модели освещения с ним, как показано здесь:

https://gavilan.blog/2018/07/29/entity-framework-core-2-1-query-types-working-with-views/

Недостатком является необходимость поддержки легких классов и представлений - вид той же проблемы, что и в решении 3.

6) SQL запросов можно использовать механизм sql запросов, что-то вроде

var ratingLIghts= dbContext.Database.SqlQuery<Rating>("select ... from Ratings");

7) Расширения Linq Есть предложения по расширению Linq с помощью запросы типа SelectExcept, как здесь

Как исключить свойство вместо Select в Lambda LINQ

один фрагмент кода предполагает, что они не работают оптимально, так как он просто заполняется NULL столбцы, которые нужно исключить, но запрос выполняется, если база данных считывает все столбцы - это неприемлемо, но я считаю, что возможно реализовать его по-другому

Так что, с моей точки зрения, самое элегантное решение с минимальным количеством код и менее подвержен дальнейшему рефакторингу потенциальных проблем является первым - спасибо Lucian Bargaoanu!

...