DbSet<something> 的 C# 泛型

Mar*_*rko 2 c# generics

我有各种方法应该能够调用将 DbSet 作为参数传递的通用方法。目前我有这个工作代码(此处简化显示):

public class MyClass
{
  private async Task<JsonResult> Delete<T>(int? id, T dbs) where T : DbSet<A>
  {
      var row = await dbs.SingleOrDefaultAsync(m => m.ID == id);
      dbs.Remove(row);
      await db.SaveChangesAsync();
      return Json(r); // definition od "r" removed from code to simplify it
  }

  public async Task<JsonResult> A(int? id)
  {
      return await Delete(id, db.A);
  }

  public async Task<JsonResult> B(int? id)
  {
      return await Delete(id, db.B);
  }

  public async Task<JsonResult> C(int? id)
  {
      return await Delete(id, db.C);
  }
Run Code Online (Sandbox Code Playgroud)

我不知道要修改“删除”方法的签名,以便方法 A、B、C... 都可以调用它。

Evk*_*Evk 5

由于您在 Delete 中引用了 ID 字段,因此您需要引入一些接口,例如

interface IHasID {
    int ID { get; }
}
Run Code Online (Sandbox Code Playgroud)

然后您需要为所有具有 ID 的实体实现该接口(在部分类中)。然后你可以像这样改变你的删除

private async Task<JsonResult> Delete<T>(int? id, DbSet<T> dbs) where T : class, IHasID {            
    var row = await dbs.SingleOrDefaultAsync(m => m.ID == id);
    dbs.Remove(row);
    await db.SaveChangesAsync();
    return Json(r); // definition od "r" removed from code to simplify it
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用(假设 A 实现了 IHasID):

public async Task<JsonResult> A(int? id) {
   return await Delete(id, db.As);
}
Run Code Online (Sandbox Code Playgroud)

如果您不想IHasID为每个实体实现(虽然这很容易,因为 ID 属性已经存在于您的实体中),则可以不使用接口(尽管不太安全,因为您将能够将任何实体传递给此 Delete方法,直到运行时您才会发现错误):

private async Task<JsonResult> Delete<T>(int? id, DbSet<T> dbs) where T : class
{
    var parameter = Expression.Parameter(typeof(T), "entity");
    // generate expression entity => entity.ID = id
    var condition = (Expression<Func<T, bool>>) Expression.Lambda(
            Expression.Equal(
                Expression.Property(parameter, "ID"),
                Expression.Constant(id)
            )
        , parameter);

    var row = await dbs.SingleOrDefaultAsync(condition);
    dbs.Remove(row);
    await db.SaveChangesAsync();
    return Json(r);
}
Run Code Online (Sandbox Code Playgroud)