如何在 DbContext 类中编写扩展方法?

5
我希望创建一个辅助方法来检查数据库中是否存在某个条目。
我已经尝试了以下代码:
public static class DbContextExtensions
{
    public static bool Exist<TModel>(this DbSet<TModel> model, string id) where TModel : class
    {
        return !string.IsNullOrEmpty(id) && model.SingleOrDefault(x => x.Id == id) != null;
    }
}

我正在遇到这个错误信息:

'TModel'不包含“Id”的定义,且找不到接受类型为'TModel'的第一个参数的扩展方法“Id”(是否缺少using指令或程序集引用?)

我的目标是:
public class PostManager
{
    private readonly _dbContext;

    public PostManager(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<IdentityResult> UpdateAsync(EditPostViewModel model)
    {
        if (_dbContext.Users.Exist(model?.UserId) && _dbContext.Posts.Exist(model?.Id))
        {
            // the user with "UserId" and the post with "Id" are existing...
        }
    }
}

我不想在PostManager类内部创建帮助方法,像这样:

public class PostManager
{
    // contructor...

    // actions...

    private bool UserExist(string id)
    {
        return !string.IsNullOrEmpty(id) && _dbContext.Users.SingleOrDefault(x => x.Id == id) != null;
    }

    private bool PostExist(string id)
    {
        return !string.IsNullOrEmpty(id) && _dbContext.Posts.SingleOrDefault(x => x.Id == id) != null;
    }
}

因为方法 UserExistPostExist 可能会在许多其他类中使用。因此,在每个类中使用它们之前,我不想重新声明它们。
我该怎么做呢?非常感谢!

您的 where TModel : class - 这告诉编译器 TModel 是 class 类型,它过于通用,不包含 id 属性。因此,如果您有任何基础实体类,请将其指向该类,例如 where TModel:Entity - Jaya
无关注释:使用model.Any(x => x.Id == i)来检查存在性,而不是使用model.SingleOrDefault(x => x.Id == i) != null - Evk
不错的观点。谢谢! - user9235753
1个回答

4
您有一个 TModel : class - 因为 TModel 是类类型,没有任何名为 Id 的属性,因此会出现错误。因此,您需要将其指向基本实体类(最好是接口 - 组合比继承更好),但这只是给您一个大致的想法 - 比如 TModel:Entity 的位置。例如:
 class BaseEntity {
   string Id {get; set;}
 }

 class Person : BaseEntity {
   string Name {get; set;}
 } 

 public static class DbContextExtensions
 {
    public static bool Exist<TModel>(this DbSet<TModel> model, string id) where TModel : BaseEntity
   {
      return !string.IsNullOrEmpty(id) && model.SingleOrDefault(x => x.Id == id) != null;
   }
 }

谢谢你的想法! - user9235753
2
考虑创建一个 interface IId { string Id {get;}},而不是一个普通的基类,并让所有应该具有 ID 的类实现此接口。这使得您的类可以从其他类派生,而不仅仅是 BaseEntity,甚至让它们使用其他属性名称作为其 ID。更好的扩展:为什么仅限于字符串 ID 的扩展函数,还可以将 ID 的类型也设置为泛型。 - Harald Coppoolse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接