Reputation: 155
public void ApproveRowTable(string tablename, List<int> idValues)
{
foreach (var x in idValues)
{
var context = new SSPModel.sspEntities();
var genRules = (from a in context.GeneralRules
where a.ID == x
select a).SingleOrDefault();
genRules.Approved_by = GlobalClass.GlobalVar;
genRules.Approved_on = DateTime.Now;
context.SaveChanges();
}
}
In my query (from a in context.GeneralRules
...) I would like to make it query base on a parameter (tablename) rather than i have to go and supply the name of the table in the query (as it is doing right now.). Any way i can get it to do that .. basic.. from a in context.TABLENAME -- TABLENAME
is a parameter that is going to be passed when the function is called. Help
Upvotes: 0
Views: 249
Reputation: 3895
This will be difficult if your entity types do not all implement the same interface or derive from the same class. If they do, it's pretty simple:
// example base type, which your entities would need to implement
public interface IApprovable
{
public int ID {get; set;}
public string Approved_by {get; set;}
public DateTime Approved_on {get; set;}
}
//...
public void ApproveRowTable<T>(List<int> idValues)
where T : IApprovable
{
using(var context = new SSPModel.sspEntities())
{
var table = context.Set<T>();
var entities = table.Where(e => idValues.Contains(e.ID));
foreach(var entity in entities)
{
entity.Approved_by = GlobalClass.GlobalVar;
entity.Approved_on = DateTime.Now;
}
context.SaveChanges();
}
}
If your entity types do not implement a common base type, then you should modify them by creating empty partials which do implement it:
public partial class GeneralRule : IApprovable {}
If you cannot do that, then you can do something like the following. (I'm assuming ID
is the PK, so we can use Find()
rather than needing to build an expression:
public void ApproveTableRows(Type entityType, IEnumerable<int> idsToApprove)
{
using(var context = new SSPModel.sspEntities())
{
var set = context.Set(entityType);
if(set == null)
throw new ArgumentException("No DbSet found with provided name", "tableSetName");
var approveByProperty = entityType.GetProperty("Approved_by");
var approveOnProperty = entityType.GetProperty("Approved_on");
if(approveByProperty == null || approveOnProperty == null)
throw new InvalidOperationException("Entity type does not contain approval properties");
foreach (object id in idsToApprove)
{
var entityInstance = set.Find(id);
approveByProperty.SetValue(entityInstance, GlobalClass.GlobalVar);
approveOnProperty.SetValue(entityInstance, DateTime.Now);
}
context.SaveChanges();
}
}
As you can see, this is less efficient, as it issues a new query for each ID rather than getting them all at once. Also, the method accepts an entity Type
rather than a string, to avoid the need to hunt down the right property by reflection. This could be improved, but really I think you should probably update your entities to implement a shared interface.
Upvotes: 1
Reputation: 12616
I assume you would like to have the method generic. When you are using EF all your tables are represented as objects, so you don't have to specify which table you want by name, just use a generic parameter.
I doubt that my solution is best, but it should work. But I have to warn you, reflection is slow and many times its usage is not right.
public void ApproveRowTable<T>(List<int> idValues)
{
var context = new SSPModel.sspEntities();
var table = context.GetType().GetProperties().OfType<T>().Single();
var genRules = (from a in table
where a.ID == x
select a).SingleOrDefault();
genRules.Approved_by = GlobalClass.GlobalVar;
genRules.Approved_on = DateTime.Now;
context.SaveChanges();
}
Upvotes: 0