Reputation: 2055
I have a public function that queries against a specific entity. I would like to replicate the function for any table I pass in but don't know how. Here is the working function I want to make dynamic:
public string MaxDepartment()
{
CPLinkEntities _context = new CPLinkEntities();
results = _context.LOG_Departments.Max(t => t.LastUpdated); // hard coded
string hex = BitConverter.ToString(results);
hex = hex.Replace("-", "");
return hex;
}
What I would really like to do here is pass in an entity to query against. All entities have a timestamp. Here is what I envision it would look like but doesn't work:
public string MaxDepartment(CPLinkEntities tableName)
{
var results = tableName.Max(t => t.LastUpdated);
string hex = BitConverter.ToString(results);
hex = hex.Replace("-", "");
return hex;
}
Calling the function from controller then would be:
CPLinkEntities context = new CPLinkEntities();
var tableName = context.LOG_Departments;
var maxDept = cf.MaxDepartment(tableName);
Upvotes: 0
Views: 2598
Reputation: 5398
I think you should mark your entity with an interface like this:
public interface ILastUpdatable
{
byte[] LastUpdated {get;set;}
}
public partial class LOG_Departments : ILastUpdatable
{
}
and then make your method expecting an object of type that implements an interface like this:
public string MaxDepartment<TLastUpdatable>(IQueryable<TLastUpdatable> updatables)
where TLastUpdatable : class, ILastUpdatable
{
var results = updatables.Max(t => t.LastUpdated);
string hex = BitConverter.ToString(results);
hex = hex.Replace("-", "");
return hex;
}
UPDATE: Also you would consider to use it as extension method:
public static class MaxUpdatableExtensions
{
public static string MaxDepartment<TLastUpdatable>(this IQueryable<TLastUpdatable> updatables)
where TLastUpdatable : class, ILastUpdatable
{
var results = updatables.Max(t => t.LastUpdated);
string hex = BitConverter.ToString(results);
hex = hex.Replace("-", "");
return hex;
}
}
and call it like this:
CPLinkEntities _context = new CPLinkEntities();
var results = _context.LOG_Departments.MaxDepartment();
Upvotes: 1
Reputation: 127583
The easiest way to do it without changing any of your existing classes (if you can, see Oleksii's answer) is to manually create the expression tree and have it select the property you want.
public static string MaxDepartment<U>(IQueryable<U> table)
{
var parameter = Expression.Parameter(typeof(U));
var property = Expression.Property(parameter, "LastUpdated");
var lambada = Expression.Lambda<Func<U, byte[]>>(property, parameter);
var results = table.Max(lambada);
string hex = BitConverter.ToString(results);
hex = hex.Replace("-", "");
return hex;
}
You would call it via
using(CPLinkEntities _context = new CPLinkEntities()) //You forgot to dispose in your original example
{
var max = MaxDepartment(_context.LOG_Departments);
//Do whatever you want with max here.
}
This will fail at runtime if you try to pass in a table that does not have a LastUpdated
property.
Upvotes: 2