如何将泛型类型的数据列表转换为另一种泛型类型的数据列表

时间:2016-11-10 06:54:03

标签: c# .net entity-framework generics

我正在尝试编写通用基本服务类,其中收到第一个通用数据列表后, Db模型实体的实际类型需要转换为新的通用视图模型数据类型。

我已尝试list.ConvertAll(),但始终为ConvertAll()方法获取构建错误。

我也试过list.Cast<TVm>().ToList()这解决了构建错误,但却出现了运行时错误。

以下是我所有类和接口的代码片段。任何帮助或建议表示赞赏。

实体类

public abstract class Entity
{
    [Key]
    [Index("IX_Id", 1, IsUnique = true)]
    public string Id { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime Created { get; set; }

    public string CreatedBy { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime Modified { get; set; }

    public string ModifiedBy { get; set; }

    [DefaultValue(true)]
    public bool Active { get; set; }
}

BaseViewModel类

public abstract class BaseViewModel<T> where T: Entity
{        

    protected BaseViewModel() { }

    protected BaseViewModel(T model)
    {
        Id = model.Id;
        Created = model.Created;
        CreatedBy = model.CreatedBy;
        Modified = model.Modified;
        ModifiedBy = model.ModifiedBy;
        Active = model.Active;
    }

    public string Id { get; set; }
    public DateTime Created { get; set; }
    public string CreatedBy { get; set; }
    public DateTime Modified { get; set; }
    public string ModifiedBy { get; set; }
    public bool Active { get; set; }
}

IBaseService接口

public interface IBaseService<T, TVm> where T : Entity where TVm : BaseViewModel<T>
{
    List<TVm> GetAll();
}

BaseService类

public abstract class BaseService<TEntity, TVm> : IBaseService<TEntity, TVm> where TEntity: Entity where TVm : BaseViewModel<TEntity>
{
    protected  IBaseRepository<TEntity> Repository;

    protected BaseService(IBaseRepository<TEntity> repository)
    {
        Repository = repository;
    }

    public virtual  List<TVm> GetAll()
    {
        List<TVm> entities;
        try
        {
            List<TEntity> list = Repository.GetAll().ToList();
            entities =  list.Cast<TVm>().ToList(); //runtime error
            entities = list.ConvertAll(x => new TVm(x)); //build error
            entities = list.ConvertAll(new Converter<TEntity, TVm>(TEntity)); //build error
        }
        catch (Exception exception)
        {                
            throw new Exception(exception.Message);
        }

        return entities;
    }

}

2 个答案:

答案 0 :(得分:2)

要创建泛型类型的实例,您需要new() - 约束。但是,这不允许您传递任何参数。你可以试试

  1. 使用Activator创建实例,如此

    entities = list.ConvertAll(x => (TVm)Activator.CreateInstance(typeof(TVm), x));

    1. new() - 约束添加到TVm类签名中的BaseService,并在您传递给它的类上添加一个方法TVm基本上执行的操作当前构造函数,但在一个方法中,并在创建新对象后调用它。

答案 1 :(得分:0)

我认为您尝试过的最佳选择是entities = list.ConvertAll(x => new TVm(x));。它编译失败的原因是,在C#继承的类中,并不一定需要与基类具有相同的构造函数。相反,您应该在BaseService内初始化TVm。此外,您的try catch阻止只会丢失一些数据并影响StackTrace,因此您最好将其删除。下面的代码应该适合你。

public abstract class BaseService<TEntity, TVm> 
    : IBaseService<TEntity, TVm> 
        where TEntity: Entity 
        where TVm : BaseViewModel<TEntity>, new()
{
    protected  IBaseRepository<TEntity> Repository;

    protected BaseService(IBaseRepository<TEntity> repository)
    {
        Repository = repository;
    }

    private TVm ConvertToViewModel(TEntity model)
    {
        return new TVm
        {
            Id = model.Id,
            Created = model.Created,
            CreatedBy = model.CreatedBy,
            Modified = model.Modified,
            ModifiedBy = model.ModifiedBy,
            Active = model.Active,
        };
    }

    public virtual  List<TVm> GetAll()
    {
        List<TEntity> list = Repository.GetAll().ToList();
        List<TVm> entities = list.ConvertAll(x => ConvertToViewModel(x));
        return entities;
    }
}