简体   繁体   中英

How do I pass an Entity Object to a function in C#

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); 

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.

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM