加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – Code First和DBContext的多态性

发布时间:2020-12-15 22:10:56 所属栏目:百科 来源:网络整理
导读:我们有一个项目,我们有多个解决方案,共享一个共同的核心库.我们的核心库包含所有与此上下文一起使用的默认实体,数据上下文和实用程序.我想让web项目扩展核心上下文,但我似乎总是得到无迁移或多个数据库.基本上,我希望能够拥有 namespace Core{ public class
我们有一个项目,我们有多个解决方案,共享一个共同的核心库.我们的核心库包含所有与此上下文一起使用的默认实体,数据上下文和实用程序.我想让web项目扩展核心上下文,但我似乎总是得到无迁移或多个数据库.基本上,我希望能够拥有

namespace Core
{
    public class BaseContext : DbContext
    {
        DBSet<SomeCoreEntity> CoreEntities {get;set;}
    }
}

然后有

namespace Web
{
    public class DerivedContext : Core.BaseContext
    {
        DBSet<SomeNewEntity> NewEntities {get;set;}
    }
}

从这里开始,我希望核心能够拥有

baseContextInstance.CoreEntities

derivedContextInstance.CoreEntites

引用相同的表,但派生的上下文也可以访问NewEntites.这样做的正确方法是什么?它是否需要web.config中的特殊内容,可能是DatabaseInitializerForType?我环顾四周,找不到任何关于如何做到这一点的好文档.

解决方法

因此,如果确保Derived和基本上下文基本上使用相同的ConnectionString键,则看起来可能.您可以让他们使用不同的密钥,但这只会导致您需要维护的重复.

注意:我正在使用包管理器中的update-database和Enable-Migrations命令.其他部署过程的一般原则应该是相同的,但我还没有测试过.

首先,创建基本上下文(以及关联的DbSet类):

namespace Core
{
    public partial class BaseContext : DbContext
    {
        public BaseContext()
        {

        }

        public BaseContext(string connectionString)
            : base(connectionString)
        {

        }

        public DbSet<SystemUser> SystemUser { get; set; }
    }

    public partial class SystemUser
    {
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        public string Forename { get; set; }
        public string Surname { get; set; }
    }
}

接下来,创建派生上下文(使用新类):

namespace Web
{
    public class DerivedContext : Core.BaseContext
    {
        public DerivedContext()
            : base("BaseContext")
        {

        }

        public DbSet<Order> Order { get; set; }
    }

    public class Order
    {
        public int Id { get; set; }
        public double Quantity { get; set; }
        public string Item { get; set; }
    }
}

到目前为止,这几乎就是你所做的事情但是,请注意两件事:

> BaseContext公开一个带有连接字符串(或连接字符串键名)的构造函数 – 它传递给DbContext中的相同构造函数
>派生上下文将键名“BaseContext”传递给BaseContext

现在,将连接字符串条目添加到Web项目中的.config文件中,使用键名BaseContext和相应的连接字符串.

<connectionStrings>
    <add name="BaseContext" connectionString="Data Source=.;Initial Catalog=TestDb;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>

通过在Package Manager控制台中输入以下内容,将迁移添加到Web项目(确保从下拉列表中选择了Web项目):

Enable-Migrations

输入创建的迁移文件,并在构造函数中将AutomaticMigrations更改为true

public Configuration()
{
    AutomaticMigrationsEnabled = true;
}

现在,当您从Web项目发布时,在PM控制台中使用以下内容:

Update-Database

它会将SystemUser和Order发布到一个新的DB(在我的例子中称为TestDb).

用法:

如果检查数据库,您会注意到它已成功创建了SystemUsers和Orders表.

如果您从应用程序运行以下代码:

using (var ctxt = new Core.BaseContext())
{
    var user1 = new Core.SystemUser()
    {
        Forename = "Obsidian",Surname = "Phoenix"
    };

    ctxt.SystemUser.Add(user1);

    ctxt.SaveChanges();
}

using (var ctxt = new DerivedContext())
{
    var user2 = new Core.SystemUser()
    {
        Forename = "John",Surname = "Doe"
    };

    ctxt.SystemUser.Add(user2);

    ctxt.SaveChanges();


    var users = ctxt.SystemUser.ToList();

    users.ForEach(u => Debug.WriteLine(string.Format("{0} {1}",u.Forename,u.Surname)));

    var order = new Order()
    {
        Id = 1,Item = "Test Item",Quantity = 1
    };

    ctxt.Orders.Add(order);

    ctxt.SaveChanges();
}

您可以看到我可以使用BaseContext和DerivedContext来读取/写入Systemuser,我可以使用DerivedContext来读取/写入Order.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读