简体   繁体   English

DbSet的C#泛型<something>

[英]C# generics for DbSet<something>

I have various methods that should be able to call a generic method passing DbSet as a parameter. 我有各种方法应该能够调用将DbSet作为参数传递的通用方法。 For the moment I have this working code (shown here simplified): 目前,我有以下工作代码(此处简化显示):

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

I don't know hot to modify the "Delete" method's signature so that methods A,B,C... can all call it. 我不知道修改“ Delete”方法的签名很热,以便方法A,B,C ...都可以调用它。

Since you reference ID field in your Delete, you need to introduce some interface, like 由于您在“删除”中引用了ID字段,因此您需要引入一些界面,例如

interface IHasID {
    int ID { get; }
}

Then you need to implement that interface (in partial class) for all entities with ID. 然后,您需要为所有具有ID的实体实现该接口(在局部类中)。 Then you can change your Delete like this 然后您可以像这样更改删除

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
}

And use like this (assuming A implements IHasID): 并像这样使用(假设A实现IHasID):

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

If you don't want to implement IHasID for every entity (though it's very easy, since ID property is already there at your entities), it's possible to do without interface (though less safe because you will be able to pass any entity to this Delete method and you won't find the error until run time): 如果您不想为每个实体都实现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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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