Reputation: 5001
I have a method updating certain record with id, and there is some entities have same structure with that table so I wonder how can I do something like below;
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);
}
instead this(it works but ugly);
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);
}
}
Upvotes: 0
Views: 35
Reputation: 3651
Easiest way to achieve this is using reflection and MakeGenericMethod
function:
1st: create an interface for types you want to delete in future:
public interface IDeletable
{
bool IsDeleted { get; set; }
int Id { get; set; }
}
2nd separate a logic function based on created interface structure
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);
}
3rd call the function with specified type
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;
...
}
}
As alternative to reflection, can be used a dictionary of repositories:
Assuming that 1st step from above has been done and that your repository is IQueryable
, than the method can looks like:
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);
}
Of course, to reduce amount of unnecessary initializations, the Dictionary
can be created as a field in the hosting object or even as a static field. In case of static field repositories will be never collected by GC.
Upvotes: 1