【问题标题】:How to generate IDbSet instead of DbSet如何生成 IDbSet 而不是 DbSet
【发布时间】:2018-10-30 10:27:02
【问题描述】:

我是C#EntityFramework 的新手,我需要维护一个活跃的软件。 我需要创建一个新表,所以我在数据库中创建了它,然后使用 EntityFramework 更新了我的模型。

但是,看起来以前的开发人员一直在直接在生成的代码(Mode.Context.cs 类)中编写代码,EntityFramework 在更新模型时正在擦除它并完全重写它。

所以我做了一个新的局部类模型。它看起来像这样:

public partial class Model : DbContext, IModel
    {
        public void SomeRandomMethod();
    }

生成的模型如下所示:

public partial class Model : DbContext
{
    public Model()
        : base("name=Model")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public DbSet<RandomTable> ARandomTable { get; set; }
}

然而,问题在于,以前,模型使用IDbSet 而不是DbSet,并且接口IModel 要求IDbSet&lt;RandomTable&gt; ARandomTable

处理这个问题的正确方法是什么?

【问题讨论】:

  • 稍微更新一下代码,这个IModel只能请求SomeRandomMethod()。清楚你的代码是什么,以及为什么你需要 IDbSet 中的 I。
  • 如果生成工具使用的是 T4 则只需更新 T4 模型即可。
  • @CodeNotFound 谢谢,用模板成功了。只需要提示看什么:)
  • 您使用的是哪种生成工具?如果是 T4 模板,则转到文件并查看设置 IDbSet 的行 (CTRL + F)。保存文件并重新生成代码。

标签: c# entity-framework edmx-designer


【解决方案1】:

通常,代表数据库的Dbcontext 有多个DbSet&lt;TEntity&gt; 属性,其中每个DbSet 代表数据库中的一个表。

TEntity 的所有非虚拟属性都代表您表中的列; TEntity 的虚属性表示表之间的关系:一对多、多对多等。

每个DbSet&lt;TEntity&gt; 都实现了IDbSet&lt;TEntity&gt;,因此无论您的旧DbContext 使用IDbSet,您都可以给它相应的DbSet

如果我理解正确的话,您的旧 DbContext 有一些实现 IDbSet&lt;...&gt; 的属性,而方法 SomeRandomMethod 使用了这些属性。

class MyOldDbContext : DbContext
{
     public IDbSet<Aentity> Aentities {get; set;}
     public IDbSet<Bentity> BEntities {get; set;} 

     public void SomeRandomMethod()
     {   // this method uses the IdBsets AEntities and BEntities:
         IDbSet<AEntity> x = this.AEntities;
         IDbSet<BEntity> y = this.BEntities;
         ... // do something with x and y
     }
}

现在你的新 DbContext。如果 DbSet 的 Entity 类型与旧的相同,则没有问题:

class MyNewDbContext : DbContext
{
     public DbSet<Aentity> Aentities {get; set;}
     public DbSet<Bentity> BEntities {get; set;} 

     public void SomeRandomMethod()
     {   // this method uses the DbSets AEntities and BEntities, which implement IDbSet
         IDbSet<AEntity> x = this.AEntities;
         IDbSet<BEntity> y = this.BEntities;
         ... // do something with x and y
     }
}

请注意,AEntities/BEntities 现在是 DbSet&lt;...&gt; 而不是 IDbSet&lt;...&gt;。因为每个DbSet&lt;...&gt; 都实现了IDbSet&lt;...&gt;,所以你的问题就解决了。

如果您的新表与旧表不同,这会有点困难。在这种情况下,您必须编写适配器属性,返回预期的 IDbSet&lt;...&gt;

class MyNewDbContext : DbContext
{
     public DbSet<Teacher> Teachers {get; set;}
     public DbSet<Student> Students {get; set;} 

     public void SomeRandomMethod()
     {   // this method uses the IdBset of AEntities and BEntities:
         IDbSet<AEntity> x = this.AEntities;
         IDbSet<BEntity> y = this.BEntities;
         ... // do something with x and y
     }

     // for SomeRandomMethod we need properties AEntities and BEntities
     // use your new DbSets to mimic the old AEntities and BEntities
     private IDbSet<AEntity> AEntities => this.Teachers
          .Join(this.Students, ...)
          .Where(...)
          .Select(...);
      // similar for BEntities
}

【讨论】:

    猜你喜欢
    • 2011-11-17
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多