5

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

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

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

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

4

1 回答 1

9

以下内容的灵感来自于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.
            }
        }
    }
}
于 2014-08-23T07:09:53.817 回答