将 ViewModels 从 API 项目绑定到 .NET CORE 2 EF 中 DAL 项目的 POCO 类
Binding ViewModels from API project to POCO classes from DAL project in .NET CORE 2 EF
最近我们在 .NET CORE 2 中启动了一个新的 (API) 项目,它在 API 项目中有一些端点,在单独的 DAL 中有数据库 (POCO) 模型 (EF CORE)项目。
通过使用 Entity Framework Core 和 FluentAPI,我们正在以代码优先的方式构建数据库。
在两个项目中都创建了一些概念验证端点和表(也具有多对多关系)。这一切似乎工作正常。
然而,我们现在面临的问题是一些 POCO classes 与其他表/POCO classes 有关系,请参见以下示例:
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 class 相同,但我只想在端点的控制器中使用一些 LINQ 对其进行测试。
但是,我立即偶然发现了几个问题。例如,所有的POCO classes都添加到我们的DBContext
class中,但是我如何将link和ViewModel
添加到它的屁股中?这还需要吗?
当我尝试使用刚刚创建的 ViewModel 作为模型并使用我们的 DbContext 作为数据上下文 class 搭建一个 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 的最新版本) .
这对你有用吗?我更改了 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; }
}
最近我们在 .NET CORE 2 中启动了一个新的 (API) 项目,它在 API 项目中有一些端点,在单独的 DAL 中有数据库 (POCO) 模型 (EF CORE)项目。
通过使用 Entity Framework Core 和 FluentAPI,我们正在以代码优先的方式构建数据库。
在两个项目中都创建了一些概念验证端点和表(也具有多对多关系)。这一切似乎工作正常。
然而,我们现在面临的问题是一些 POCO classes 与其他表/POCO classes 有关系,请参见以下示例:
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 class 相同,但我只想在端点的控制器中使用一些 LINQ 对其进行测试。
但是,我立即偶然发现了几个问题。例如,所有的POCO classes都添加到我们的DBContext
class中,但是我如何将link和ViewModel
添加到它的屁股中?这还需要吗?
当我尝试使用刚刚创建的 ViewModel 作为模型并使用我们的 DbContext 作为数据上下文 class 搭建一个 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 的最新版本) .
这对你有用吗?我更改了 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; }
}