gpt4 book ai didi

c# - 从另一个项目扩展DbContext

转载 作者:太空宇宙 更新时间:2023-11-03 12:40:14 34 4
gpt4 key购买 nike

我正在尝试通过我正在从事的项目实现某些层分离。我的想法是,我可以使用网站具有的任何功能并对其进行调整。例如,如果您使用诸如News之类的东西,并且希望将该功能添加到网站,那么在代码中,您只需要导入新闻服务以及模型,数据层等即可。

请注意,我将Ninject用作项目的一部分以注入依赖项,因此我无需引用具体的类,而仅引用合同。

我有我的主要项目和数据层,如:

public class MainDbContext : CustomIdentityDbContext, IMainDbContext
{

}


如您所见,它扩展了CustomIdentityDbContext,其外观如下:

public class CustomIdentityDbContext : IdentityDbContext<CustomUser>, ICustomIdentityDbContext
{
public CustomIdentityDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole");
modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
modelBuilder.Entity<IdentityRole>().ToTable("Role");
modelBuilder.Entity<AzularisUser>().ToTable("User");
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}

public static DbContext Create()
{
return new CustomIdentityDbContext();
}
}


我的问题是,我需要有一个News表,然后我需要EF6来映射该表,就像对Identity一样。我不知道如何建立这种关系。如何在我的MainDbContext中添加 DbSet<News> News { get; set; },而不必在那里写该行并引用News对象。因此,我尝试实现在引用服务时动态地将其添加到MainDbContext类中,因为该服务将触发所有其他类通过ninject和绑定创建自己。

换句话说,新闻数据层需要将自身插入MainDbContext中,而MainDbContext在其引用中不知道它。这样的事情可能吗?如果是这样,我将如何实现?

这是我尝试过的:

public class NewsDbContext : DbContext, INewsDbContext
{
public DbSet<News> News { get; set; }
public NewsDbContext() : base("DefaultConnection") { }

public IEnumerable<INews> QueryNews()
{
return News;
}
}


上面的代码可以编译并运行,但是,它不会创建表,并且当我尝试查询表或插入记录时,由于表不存在,它将中断。我不太确定如何做到这一点,而且我非常没主意。这样的事情可能吗?

编辑:

我意识到我可能没有正确地解释自己。让我再试一遍。我有一个多层结构。我有一个服务,数据,域和DTO层。这4个层组成一个插件。在这4层之上,我还有4个是这些层的接口,换句话说就是契约。我使用Ninject将合同绑定到实现层,以便主项目从不实际引用项目中的实现层。因此,我试图将数据层插入主项目的数据层,而主项目数据层实际上并未引用插件的数据层。问题在于该插件将具有其自己所需的表。我希望在首次运行项目时使用EF6自动创建这些表。

我的主项目也以与插件相同的方式进行拆分,它具有所有4层以及一个Manager层。管理器是服务的集合,没有其他目的,它只是在Ninject的帮助下基于合同实例化它们。项目的核心包含所有视图,脚本和CSS文件,但它引用管理器的界面。使用ninject,我创建了管理器的实例。管理器再次拥有所有对合同的引用,并通过ninject创建这些合同的实例。服务引用数据层的合同,数据层将查询该信息并将结果带回服务,该服务将被传递回控制器。我希望这可以更好地解释我的结构。通过这种方法,我试图创建一个真正的模块化项目,您可以在其中交换dll的实现并使项目继续运行,而无需重新编译整个过程。我可以在2个dll上具有两个完全独立的功能,但是只要它们实现相同的合同,无论文件夹中包含哪个dll,网站都可以正常工作。

我刚才描述的所有内容都可以使用EF6进行工作。我在DAPPER上有一个非常相似的结构,在您编写自己的查询时,它的所有内容都很好,所以我没有任何问题。我正在尝试使用EF6复制此内容。再说一遍,我的问题是,当唯一引用的是服务接口时,如何获得EF6来创建表,如何动态添加它们。也许接口可以具有MapTables函数,但是我不确定如何完成对EF6的动态添加。

我有一个主意,我不确定这是否行得通,也不确定如何做,但是如果我将数据库上下文作为一种类型而不是扩展它呢?

最佳答案

我已经部分解决了我的问题。一旦有完整的解决方案,我将以此为答案并进行更新。到目前为止,我已经学习了如何生成表。它与主项目的数据库上下文中的以下代码一起使用:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var entityTypes = assembly
.GetTypes()
.Where(t =>
t.GetCustomAttributes(typeof(PersistentAttribute), inherit: true)
.Any());

foreach (var type in entityTypes)
{
entityMethod.MakeGenericMethod(type)
.Invoke(modelBuilder, new object[] { });
}
}

base.OnModelCreating(modelBuilder);
}


上面的代码将确保为添加了“ PersistentAttribute”的任何类创建表。我的下一个问题是尝试从外部DLL查询。因此,新闻项目的数据层需要能够通过以某种方式传递在主项目中创建的上下文来查询自身。多亏了ninject,我对此没有什么想法,一旦发现,我将发表更多。

关于c# - 从另一个项目扩展DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39317062/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com