【问题标题】:Bounded Contexts and EF Code First - How to put them together?限界上下文和 EF 代码优先 - 如何将它们放在一起?
【发布时间】:2014-10-16 17:50:22
【问题描述】:

恕我直言,最出色的 DDD 概念之一是应用程序中分离上下文的能力。但我对如何将所有东西放在一起工作感到困惑。

首先,我知道一件事与另一件事无关。但我的问题正好落在基础设施/ORM 部分。

例如,我有一个名为 Procedure(医疗程序)的域对象。在注册上下文中,唯一重要的是代码名称。但在 Procedure Management Context 中,我有很多其他字段,例如 Price,它们都属于这个特定的上下文。

如何使用 EF Code First 让两个具有不同属性的同名实体(在不同的上下文中)?基本上,我想将所有字段保存在同一个表中,但在一个上下文中只检索 2 个字段,而在另一个上下文中检索所有字段。我怎样才能做到这一点?

【问题讨论】:

    标签: .net entity-framework ef-code-first domain-driven-design bounded-contexts


    【解决方案1】:

    以下内容的灵感来自Shrink EF Models with DDD Bounded Contexts 文章。

    领域模型:

    namespace SO25454395.Domain.Registration
    {
        using System;
    
        public class Procedure
        {
            public int Id { get; set; }
            public Guid Code { get; set; }
            public string Name { get; set; }
        }
    }
    

    .

    namespace SO25454395.Domain.ProcedureManagement
    {
        using System;
    
        public class Procedure
        {
            public int Id { get; set; }
            public Guid Code { get; set; }
            public string Name { get; set; }
            public decimal Price { get; set; }
        }
    }
    

    有界上下文:

    namespace SO25454395.Infrastructure
    {
        using System.Data.Entity;
    
        public class RegistrationContext : BaseContext<RegistrationContext>
        {
            public DbSet<Domain.Registration.Procedure> Prodedures { get; set; }
        }
    }
    

    .

    namespace SO25454395.Infrastructure
    {
        using System.Data.Entity;
    
        public class ProcedureManagementContext : BaseContext<ProcedureManagementContext>
        {
            public DbSet<Domain.ProcedureManagement.Procedure> Procedures { get; set; }
        }
    }
    

    默认的 Code First 行为是为每个上下文创建一个新数据库,因此我们使用基类禁用它并指定应在所有上下文之间共享的数据库。

    namespace SO25454395.Infrastructure
    {
        using System.Data.Entity;
    
        public class BaseContext<TContext> : DbContext where TContext : DbContext
        {
            static BaseContext()
            {
                Database.SetInitializer<TContext>(null);
            }
    
            protected BaseContext() : base("Database")
            {
    
            }
        }
    }
    

    最后,我们需要一个包含用于构建完整模型的所有类的上下文。此上下文用于初始化。

    namespace SO25454395.Infrastructure
    {
        using SO25454395.Domain.ProcedureManagement;
        using System.Data.Entity;
    
        public class DatabaseContext : DbContext
        {
            public DbSet<Procedure> Procedures { get; set; }
    
            public DatabaseContext() : base("Database")
            {
            }
        }
    }
    

    测试:

    namespace SO25454395.Tests
    {
        using SO25454395.Infrastructure;
        using System;
        using System.Linq;
        using Xunit;
    
        public class BoundedContextTests
        {
            [Fact]
            public void Test()
            {
                using (var databaseContext = new DatabaseContext())
                {
                    databaseContext.Database.Initialize(true);
                }
    
                var code = Guid.NewGuid();
                var name = "Name";
                var price = 123.45m;
    
                using (var procedureManagementContext = new ProcedureManagementContext())
                {
                    var procedure = new Domain.ProcedureManagement.Procedure { Code = code, Name = name, Price = price };
                    procedureManagementContext.Procedures.Add(procedure);
                    procedureManagementContext.SaveChanges();
                }
    
                using (var registrationContext = new RegistrationContext())
                {
                    var procedure = registrationContext.Prodedures.Single(p => p.Code == code);
                    Assert.Equal(name, procedure.Name);
                    // procedure.Price is not available here.
                }
            }
        }
    }
    

    【讨论】:

    • 在上面的“DatabaseContext”中,我应该指向Procedure实体的命名空间是什么?
    • DatabaseContext 代表整个模型,因此是所有其他模型的组合。在示例代码中,我只是重用了 ProcedureManagement 中的类,因为它包含所有过程属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2016-03-18
    相关资源
    最近更新 更多