【问题标题】:How to write an extension method in DbContext class?如何在 DbContext 类中编写扩展方法?
【发布时间】:2018-02-19 16:53:18
【问题描述】:

我想创建一个辅助方法来检查数据库中是否存在项目。

我试过了:

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
  • 无关说明:使用model.Any(x =&gt; x.Id == i) 而不是model.SingleOrDefault(x =&gt; x.Id == i) != null 来检查是否存在。
  • @Evk 好点。谢谢!

标签: c# entity-framework


【解决方案1】:

你有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;
   }
 }

【讨论】:

  • 感谢您的想法!
  • 考虑创建一个interface IId { string Id {get;}} 而不是一个通用的基类,并让所有应该有ID 的类实现这个接口。这使您的类可以从 BaseEntity 以外的其他类派生,甚至可以让它们使用其他属性名称作为其 ID。更好的扩展:为什么将扩展功能限制为字符串 ID,让 ID 的类型也通用
猜你喜欢
  • 2014-10-15
  • 2012-03-10
  • 2014-01-23
  • 2018-02-23
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多