如何
我想写一个了通用基础服务类那里接收数据的拳头泛型列表作为实际类型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;
}
}
创建一个通用类型的实例,你需要就可以了new()
-constraint。但是,这不允许您将任何参数传递给它。你可以尝试要么
-
使用激活创建一个实例,这样
entities = list.ConvertAll(x => (TVm)Activator.CreateInstance(typeof(TVm), x));
或
- 添加
new()
- 在BaseService
类别签名中限制为TVm
,并在您传递给它的类中添加一个方法作为TVm
基本上做当前的构造函数所做的事情,但在一个方法中,并在创建新对象后调用它。
也可以使用映射工具,如AutoMapper(https:// github。com/AutoMapper/AutoMapper) –
1是非常有用,工作正常。在问这个问题之前,我尝试了2次,但是这打破了我目前的实施。这就是为什么我拒绝添加new()约束。非常感谢您的好意。 –
我认为您尝试的最佳选择是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;
}
}
谢谢你的建议。因此,我不使用new()约束,因此无法创建TVm的实例。 –
@ Md.SabbirAhamed,因为我不熟悉整个图片,所以添加'new()'约束是不可接受的。无论如何,我很高兴你的问题得到解决 –
是的,我很高兴,问题解决了:)。再次感谢你。很明显,您的共享知识将来可能会在我的项目的这个或其他任何项目中生效 –
它给你的构建错误是什么?什么是运行时错误?请编辑问题 –