Связывание ViewModels из проекта API с классами POCO из проекта DAL в .NET CORE 2 EF - PullRequest
0 голосов
/ 29 мая 2018

Недавно мы запустили новый (API) проект в .NET CORE 2, который имеет некоторые конечные точки в проекте API и моделях базы данных (POCO) (EF CORE) в отдельном проекте DAL.

Используя Entity Framework Core и FluentAPI, мы создаем базу данных в первую очередь.

Некоторые конечные точки и таблицы для проверки концепции (также со связями «многие ко многим») создаются в обоих проектах.Кажется, что все это работает нормально.

Проблема, с которой мы сталкиваемся сейчас, заключается в том, что некоторые классы POCO имеют отношения к другим таблицам / классам POCO, см. Пример ниже:

public class Medium
{
    public Medium()
    {
        this.Hold = new HashSet<Hold>();
        this.InExMedium = new HashSet<InExMedium>();
    }

    public long MediumID { get; set; }

    public long SolutionID { get; set; }

    public string Name { get; set; }

    public Solution Solution { get; set; }

    public ICollection<Hold> Hold { get; set; }

    public ICollection<InExMedium> InExMedium { get; set; }
}

В нашей конечной точке Medium мы не хотим, чтобы свойства Hold и InExMedium были видны или оценивались в функции ModelState.IsValid.

Нашим первым решением было сделать эти свойства internal вместоpublic, который работал в начале.Однако вскоре мы поняли, что это неправильный способ, поскольку другие функции больше не могут использоваться должным образом (например, LINQ ).

Решение, по крайней мере, мне кажется, состоит в том, чтобы использоватьслой между ними, ViewModels.

Для вышеуказанной задачи я создал следующее (тест) ViewModel:

public class MediumViewModel
{
    public Medium Medium { get; set; }

    public InExMedium InExMedium { get; set; }

    public Solution Solution { get; set; }

    public Hold Hold { get; set; }
}

Я знаю, что ViewModel совпадает с оригиналомКласс POCO, но я просто хочу проверить его с помощью некоторого LINQ в контроллере конечной точки.

Однако я сразу же наткнулся на несколько вопросов.Например, все классы POCO добавлены к нашему классу DBContext, но как я могу правильно связать ViewModel с ним?Это вообще нужно?

Когда я пытаюсь Scafold API-контроллер с только что созданным ViewModel в качестве модели и нашим DbContext в качестве класса контекста данных, я получаю следующую ошибку:

There was an error running the selected code generation: 'Could not add Model type MyProject.API.Viewmodels.MediumViewModel' to DbContext 'MyProject.MyDbContextClass'. Please make sure that 'MyProject.MyDbContextClass' has a DbSet property for 'MyProject.API.Viewmodels.MediumViewModel'

Как лучше всегосправиться с этим?Я читал кое-что о AutoMapper, но я предпочитаю не использовать другую библиотеку для достижения этой цели.

В API-контроллере я использую DbContext следующим образом:

    public class MediaController : TrsBaseController
    {

        public MediaController(MyDbContext context)
            : base(context)
        {

        }

        //// GET: api/media
        [HttpGet]
        public async Task<IEnumerable<Medium>> GetMedia()
        {
            return await this.Context.Medium.ToListAsync();
        }
    }

При использовании ViewModel могу ли я по-прежнему использовать DbContext, как указано выше, или я должен реализовать его по-другому?

Я посмотрел вокруг, чтобы найти хорошие учебники по этой проблеме, но я думаю, что я прибегаю к помощи неправильных ключевых слов, так как не могу найти много учебников (которые также актуальны в .NET CORE2).

1 Ответ

0 голосов
/ 29 мая 2018

Это работает для вас?Я изменил MediumViewModel, чтобы использовать в качестве примера.Вы можете сделать это асинхронно!

public class MediaController : TrsBaseController
{

    public MediaController(MyDbContext context)
        : base(context)
    {

    }

    //// GET: api/media
    [HttpGet]
    public IEnumerable<MediumViewModel> GetMedia()
    {
        var result = this.Context.Medium.ToList();
        return result.Select(x=> new MediumViewModel {Medium = x.MediumID, Solution  = x.SolutionID}); // and so on
    }
}

public class MediumViewModel
{
    public long Medium { get; set; }

    public long Solution { get; set; }
}
...