【问题标题】:using a generic method when using interface使用接口时使用泛型方法
【发布时间】:2017-12-07 05:47:09
【问题描述】:

我陷入了泛型问题。 我有一个基于对象类型从 DbContext 对象返回 DbSet 的方法。

现在我想编写 I 方法,在该方法中传入一个对象,该对象实现了一个名为 IBaseData 的接口(所有实体都实现了该接口)。我想使用现有方法根据 IBaseData 对象的类型返回正确的 DbSet,但我无法让它工作。

我尝试过各种版本的 、typeof 和 gettype。

现有方法

public GenericRepository<T> GetRepo<T>() where T : class
{
    return new GenericRepository<T>(_context);
}

新方法(这正是我想要做的

public async Task SetDateLastInvoked<T>(IBaseData data, int id)
{
    var tmp = GetRepo<typeof(data)>().Where(obj => obj.Id.Equals(id));
    tmp.DateLastInvoked = DateTime.Now;

    await SaveChangesAsync();
}

【问题讨论】:

  • 如果您使用的是 EF,您将遇到的问题是 EF 不支持查询接口属性,至少我上次没有检查过。即使您使用的是泛型方法,这也适用
  • 啊欧凯。但是,如果所有实体都派生自一个实现该接口的类呢?所以我不传入接口,而是传入实现它的对象,如果你明白我的意思吗?
  • 如果您将泛型类型限制在基本类型而不是接口上,我相信它会起作用,但我还没有测试过
  • 如果 data 的类型在编译时未知,要调用泛型方法,您需要按照此处所述的反射 stackoverflow.com/questions/232535/…
  • data 对象进入SetDateLastInvoked 的来源是什么?更具体地说,它是否附加到那个点的上下文?

标签: c# entity-framework generics


【解决方案1】:

我假设你正在做类似的事情:

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

然后一个方法会喜欢

public GenericRepository<T> GetRepo<T>() 
  where T : class
{
  return new GenericRepository<T>(_context);
}

public async Task SetDateLastInvoked<T>(int id)
  where T : class, IBaseData
{
  var tmp = GetRepo<T>().FirstOrDefault(obj => obj.Id == id));
  tmp.DateLastInvoked = DateTime.Now;

  await SaveChangesAsync();
}

用法:

public MyClass : IBaseData 
{ 
  public Id { get; set }
}

SetDateLastInvoked<MyClass>(1);

【讨论】:

  • @TheRuler 将您的 GetRepo 限制为 where T: IBaseData 也不会有什么坏处 - 将阻止传递与您的实体完全无关的某些类型(这将在运行时失败)。
  • 我想我现在已经做到了.. 不是你说的那样,而是where T : class, IBaseData
【解决方案2】:

根据之前的答案结束了这个:

public async Task SetLastInvoked<T>(int id) where T : class, IBaseData
{
    var tmp = await GetRepo<T>().Single(obj => obj.Id.Equals(id));
    tmp.DateLastInvoked = DateTime.Now;

    await SaveChangesAsync();
}

我还基于相同的模式创建了另一种方法:

public async Task DeleteItem<T>(int id, bool removeRow) where T : class, IBaseData
{
    if (removeRow)
    {
        GetRepo<T>().Delete(await GetRepo<T>().Single(obj => obj.Id.Equals(id)));
    }
    else
    {
        var tmp = await GetRepo<T>().Single(obj => obj.Id.Equals(id));
        tmp.Active = false;
    }

    await SaveChangesAsync();
}

【讨论】:

    猜你喜欢
    • 2014-12-15
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2011-03-14
    相关资源
    最近更新 更多