【问题标题】:Max value of a column using generics使用泛型的列的最大值
【发布时间】:2017-09-13 09:27:29
【问题描述】:

我正在做一个项目。它遵循“工作单元”模式。我想编写一个动态方法,我将传递表名,它将返回主键列的最大值,或者我将传递表和列名,它将返回该列的最大值。它看起来像这样--

public int GetMaxPK<T>()
{
    GetMaxId= ??
    return GetMaxId;
}

有可能吗?我怎样才能做到这一点?或者有什么建议?

【问题讨论】:

  • 您可以使用where 约束并指定支持此类值的接口或基本类型:public int GetMaxPK&lt;T&gt;() where T is BaseType

标签: c# linq generics lambda generic-programming


【解决方案1】:

在我的项目中,我在 mvc 控制器中编写了这样的 maxId--

public class PurchaseOrderController : Controller
{    
   private IPurchaseOrder interfaceRepository;

    public PurchaseOrderController()
    {
        if (interfaceRepository==null)
        {
            this.interfaceRepository= new Repository();
        }
    }
    int maxId=interfaceRepository.GetMaxPK(a=>a.POMSTID);
}

这里

a=>a.POMSTID

是您要查询的列选择器。假设您要选择名为“PODETID”的列,那么列选择器将是这样的--

a=>a.PODETID

现在在界面中--

    public interface IPurchaseOrder:IRepository<PURCHASEORDERMASTER>
    {

    }

这里的“PURCHASEORDERMASTER”是我的查询表或 TEntity。

public interface IRepository<TEntity> where TEntity : class
{
    int GetMaxPK(Func<TEntity, decimal> columnSelector);
}

现在在存储库(或具体)类(继承接口)中,您必须在其中调用数据库,您必须像这样编写--

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
 {   

    public int GetMaxPK(Func<TEntity, decimal> columnSelector)
    {
        var GetMaxId = db.Set<TEntity>().Max(columnSelector);
        return GetMaxId;
    }
 }

这里 db 是数据库上下文,decimal 是我的查询列的数据类型。

【讨论】:

  • Excellent.your answer解决了我的问题。很多天我都在尝试动态获取maxID,但找不到解决方案。根据你的回答,它完美地给了我maxID。谢谢你的回答。
【解决方案2】:

您可以使用一个属性定义interface

public interface IMax
{
    int Id { get; set; }
}

然后你的泛型类应该实现这个接口:

public class yourClass<T> where T : class , IMax

最后:

public int GetMaxPK()
{
    GetMaxId= yourTable.Max(c => c.Id);
    return GetMaxId;
}

你的完整代码应该是这样的:

public class yourClass<T>  where T : class, IMax
{
    public int GetMaxPK(IEnumerable<T> yourTable)
    {
        var GetMaxId = yourTable.Max(c => c.Id);
        return GetMaxId;
    }
}

【讨论】:

  • 我对不同的表使用不同的名称(作为主键列)而不是用作“id”。所以我必须传递列名或选择主键列的任何名称。
  • @MohammadSadiqurRahman 当你使用泛型时,你应该尽可能地使用更通用的逻辑。因此,我建议将您的 PK 重命名为 ids 或所有表中相同的名称..
  • 我也可以让我的列名动态化吗?
  • @MohammadSadiqurRahman 您可以使用System.Linq.Dynamic,正如我在这个问题中回答的stackoverflow.com/a/44143131/2946329 但是我仍然建议将您的 PK 重命名为在所有表格中都相同的名称,这会使您的代码更具可读性和可重复使用。
  • @MohammadSadiqurRahman 也可以使用反射,一般来说非常昂贵,不建议用于这种场景。
【解决方案3】:

您可以考虑使用类似于 Max 扩展方法的方法

TResult Max<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);

当适应你的场景时

public int GetMaxPK<TTable>(IEnumerable<TTable> table, Func<TTable, int> columnSelector) {
    var maxId= table.Max(columnSelector);
    return maxId;
}

或者假设源已经在封装类内部,例如DbContext

DbContext db;

//...

public int GetMaxPK<TTable>(Func<TTable, int> columnSelector) {
    var maxId = db.Set<TTable>().Max(columnSelector);
    return maxId;
}

并像这样称呼

var maxId = myClass.GetMaxPK<TableName>(t => t.PKColumnName);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    相关资源
    最近更新 更多