【问题标题】:Binding ViewModels from API project to POCO classes from DAL project in .NET CORE 2 EF在 .NET CORE 2 EF 中将 API 项目中的 ViewModel 绑定到 DAL 项目中的 POCO 类
【发布时间】:2018-05-29 12:31:17
【问题描述】:

最近我们在 .NET CORE 2 中启动了一个新 (API) 项目,该项目在 API 项目中有一些端点,在单独的 DAL 项目中有数据库 (POCO) 模型 (EF CORE)。

通过使用 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 端点中,我们不希望 HoldInExMedium 属性在 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 也链接到它呢?这甚至需要吗?

当我尝试使用刚刚创建的 ViewModel 作为模型和我们的 DbContext 作为数据上下文类来搭建 API 控制器时,我收到以下错误:

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 CORE 2 的最新版本)。

【问题讨论】:

  • 好吧,AutoMapper 应该可以完成这项工作,但由于您不想不使用它,您可以想办法只返回您想要的属性。看看这个教程,我相信它对你有用。在您的 DbSet 中,在将模型返回给客户端之前,指定您想要返回的属性,就像此人在此处所做的 c-sharpcorner.com/UploadFile/f7a3ed/…
  • 我相信您正在寻找的术语是“实体框架投影”。 Automapper 有一个扩展来执行此操作,但也可以通过使用 LINQ 的 Select 语句轻松完成。有关示例,请参阅此 post here

标签: c# entity-framework asp.net-mvc-viewmodel


【解决方案1】:

这对你有用吗?我更改了 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; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 2017-09-29
    • 2012-06-28
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    相关资源
    最近更新 更多