我有一个用id更新某个记录的方法,并且有一些实体与该表具有相同的结构,所以我想知道我该如何做以下的事情;
public void deleteCarwithId(int id, int type)
{
string[] brands = { "BMW", "VOLKSWAGEN", "RENAULT", "FIAT" };
T entity = Convert.ToEntity(brands[type]);//ofc there is no such a method yet
var result =UnitOfWork.Repository<entity>().FirstOrDefault(u => u.ID == id);
result.IsDeleted = true;
Update(result);
}
而不是这个(它有效但丑陋);
public void deleteCarwithId(int id, int type)
{
string[] brands = { "BMW", "VOLKSWAGEN", "RENAULT", "FIAT" };
if (brands[type] == "BMW")
{
var result = UnitOfWork.Repository<BMW>().FirstOrDefault(u => u.ID == id);
result.IsDeleted = true;
Update(result);
}
if (brands[type] == "VOLKSWAGEN")
{
var result = UnitOfWork.Repository<VOLKSWAGEN>().FirstOrDefault(u => u.ID == id);
result.IsDeleted = true;
Update(result);
}
}
答案 0 :(得分:1)
实现这一目标的最简单方法是使用反射和MakeGenericMethod
函数:
1st:为将来要删除的类型创建一个界面:
public interface IDeletable
{
bool IsDeleted { get; set; }
int Id { get; set; }
}
第二个基于创建的接口结构分离逻辑功能
public void Delete<T>(UnitOfWork unitOfWork, int id) where T: IDeletable
{
var repository = (Repository<T>)typeof(UnitOfWork).GetMethod("Repository")
.MakeGenericMethod(typeof(T)).Invoke(new UnitOfWork(), new object[0]);
var item = repository.FirstOrDefault(x => x.Id == id);
item.IsDeleted = true;
Update(item);
}
第3次调用指定类型的函数
public void deleteCarwithId(int id, int type)
{
var method = typeof(Program).GetMethod("Delete"); // Binding parameters could requires
switch(type)
{
case 0: method.MakeGenericMethod(typeof(BMW))
.Invoke(this, new object[]{unitOfWork, id});
return;
...
}
}
作为反射的替代方法,可以使用存储库的字典:
假设上面的第一步已经完成并且您的存储库是 IQueryable
,那么该方法可能如下所示:
public void deleteCarwithId(int id, int type)
{
var source = new Dictionary<int, IQueryable<IDeletable>>
{
{0, unitOfWork.Repository<BMW>() }
// all other types
};
var repository = source[i];
var item = repository.FirstOrDefault(x => x.Id == id);
item.IsDeleted = true;
Update(item);
}
当然,为了减少不必要的初始化量,可以将Dictionary
创建为托管对象中的字段,甚至可以创建为静态字段。如果是静态字段,GC将从不收集。