提供一个方法返回一个接口中的实体

本文关键字:一个 实体 接口 返回 方法 | 更新日期: 2023-09-27 18:02:34

好的,我正在尝试为我的视图模型创建一个接口,它提供了一对强制方法和一个属性。

interface IVmConvertible
{
    IVmConvertible Model { get; set; }
    Entity ConvertToModel(IVmConvertible target);
    IVmConvertible ConvertToViewModel(IVmConvertible target);
}

我遇到的麻烦是抽象我的实体框架类,以便ConvertToModel方法的返回类型将解释我的任何实体。我的ConvertToViewModel方法很好,因为我所有的视图模型都实现了这个接口。我想过为我所有的实体创建一个接口,但如果我改变自动生成的代码,每次我改变数据库时,它就会被擦除。

我如何抽象我的ConvertToModel方法返回任何实体?

提供一个方法返回一个接口中的实体

可能的解决方案是:

interface IVmConvertible<T>
{
    IVmConvertible Model { get; set; }
    T ConvertToModel(IVmConvertible target);
    IVmConvertible ConvertToViewModel(IVmConvertible target);
}

那么你潜在的CarVm for Car实体应该是这样的:

public class CarVm : IVmConvertible<Car>
{
...
}

另一个选择是您从数据库优先方法移动到代码优先方法。启用迁移,创建当前数据库的快照,然后继续从代码更改数据库。这样你的实体类就不会被溢出,因此你可以在它们上面实现一些其他的接口,比如IEntity,然后使用非泛型方法:

interface IVmConvertible
{
    IVmConvertible Model { get; set; }
    IEntity ConvertToModel(IVmConvertible target);
    IVmConvertible ConvertToViewModel(IVmConvertible target);
}

这个解决方案可能适合也可能不适合您的需要。这是我们这里做的事情,我不确定我完全理解你的要求。在这些示例中,我假设Entity类使用不同的接口,而不是IVmConvertable我没有提到泛型(这可能是一个很好的方法,因为已经讨论过了)

手动

    创建一个单独的类文件,如EntitesPartialClasses.cs
  1. 为每个实体添加部分类
  2. 让部分类实现接口等(你甚至可以派生!)

类文件:

public partial class MyEntityClass: IMyEntity {
     .... 
}

最好显式地实现接口,以便调用者在能够使用这些方法之前强制对其进行类型转换。既然您期望接口,这是没有问题的,但其他人不会感到困惑

public partial class MyEntityClass : IMyEntity {
     IMyEntity.MyMethod() { }
}

如果你确实从基类派生,让基类以同样的方式实现接口。

修改t4模板文件

我这样做是为了将edmx文件中的文档属性添加到类输出中。打开Entities.tt文件(或者你叫它什么),点击
  1. 查找第一个循环(foreach(var entity in ...)
  2. 查找类定义(以<#=Accessibility.ForType(entity)#>
  3. 开头)
  4. 更新定义以添加自定义接口

这可能需要一些工作,因为EF类也可以有另一个类作为基类。我认为相关的修改应该是这样的:

//-- original --
<#=Accessibility.ForType(entity)#><#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>

{

//-- new ---
<#=Accessibility.ForType(entity)#><#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#>
    : IMyEntity <#=code.StringBefore(", ", code.Escape(entity.BaseType))#>
{
    // implement IMyEntity here, in the TT file