假设方法返回接口中的实体

时间:2014-05-09 04:37:48

标签: c# entity-framework

好的,我正在尝试为我的viewmodel创建一个接口,它提供了一些强制方法和一个属性。在这里。

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

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

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

2 个答案:

答案 0 :(得分:1)

可能的解决方案是:

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

因此,您潜在的CarVm for Car实体将如下所示:

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

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

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

答案 1 :(得分:0)

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

手动

  1. 创建单独的类文件,例如EntitesPartialClasses.cs
  2. 为每个实体添加部分类
  3. 让部分类实现接口/ etc(你甚至可以派生!)
  4. 班级档案:

    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. 更新定义以添加自定义界面
    5. 这可能需要一些工作,因为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