有界背景和EF代码首先 - 如何把它们放在一起? [英] Bounded Contexts and EF Code First - How to put them together?
问题描述
首先,我知道有一件事与其他事情无关。但是我的问题完全在基础设施/ ORM部分。
例如,我有一个名为 Procedure 的域对象(医疗程序)。在注册语境中,只有重要的是代码和名称。但是在过程管理环境中,我有很多其他的字段,如 Price ,属于这个上下文。
我如何使用EF代码优先使用具有不同属性的两个具有相同名称的实体(在不同的上下文中)?基本上,我想保存在同一个表中的所有字段,但在一个上下文中仅检索2个字段,而在其他的上下文中只检索所有字段。如何实现这一点?
以下是由收缩具有DDD有界上下文的EF模型文章。
域模型:
命名空间SO25454395.Domain.Registration
{
using System;
public class Procedure
{
public int Id {get;组; }
public Guid Code {get;组; }
public string Name {get;组;
}
}
。
命名空间SO25454395.Domain.ProcedureManagement
{
using System;
public class Procedure
{
public int Id {get;组; }
public Guid Code {get;组; }
public string Name {get;组; }
public decimal价格{get;组;
}
}
有界的上下文
命名空间SO25454395.Infrastructure
{
using System.Data.Entity;
public class RegistrationContext:BaseContext< RegistrationContext>
{
public DbSet< Domain.Registration.Procedure> Prodedures {get;组;
}
}
。
命名空间SO25454395.Infrastructure
{
using System.Data.Entity;
public class ProcedureManagementContext:BaseContext< ProcedureManagementContext>
{
public DbSet< Domain.ProcedureManagement.Procedure>程序{get;组; }
}
}
默认的Code First行为是创建一个新的数据库为每个上下文,所以我们禁用这个使用基类,并指定应该在所有上下文之间共享的数据库。
命名空间SO25454395.Infrastructure
{
using System.Data.Entity;
public class BaseContext< TContext> :DbContext其中TContext:DbContext
{
static BaseContext()
{
Database.SetInitializer< TContext>(null);
}
protected BaseContext():base(Database)
{
}
}
}
最后,我们需要一个包含用于构建完整模型的所有类的上下文。此上下文用于初始化。
命名空间SO25454395.Infrastructure
{
使用SO25454395.Domain.ProcedureManagement;
使用System.Data.Entity;
public class DatabaseContext:DbContext
{
public DbSet< Procedure>程序{get;组;
public DatabaseContext():base(Database)
{
}
}
}
测试:
命名空间SO25454395.Tests
{
使用SO25454395.Infrastructure;
使用系统;
使用System.Linq;
使用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();
}
使用(var registrationContext = new RegistrationContext())
{
var procedure = registrationContext.Prodedures.Single(p => p.Code ==码);
Assert.Equal(name,procedure.Name);
// procedure.Price在这里不可用。
}
}
}
}
IMHO, one of the most brilliant DDD concept is the ability of separate contexts in a application. But I'm confused on how I can put everything to work together.
First, I know that one thing is not related to other. But my question falls exactly on the Infrastructure/ORM part.
For example, I have a domain object called Procedure (a medical procedure). In the Context of Registration, only thing that matters is Code and Name. But in Procedure Management Context, I have a lot of other fields like Price that belongs to this context specific.
How I can have two entities with same name (in different contexts) with different properties using EF Code First? Basically, I want to save all fields in the same table, but retrieve only 2 fields in one context, and all fields in other. How I can achieve this?
The following is inspired by the Shrink EF Models with DDD Bounded Contexts article.
Domain models:
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; }
}
}
Bounded contexts:
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; }
}
}
The default Code First behavior is to create a new database for each context, so we disable this using a base class and specify the database that should be shared among all contexts.
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")
{
}
}
}
Finally we need a context containing all classes used to build the complete model. This context is used for initialization.
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")
{
}
}
}
Test:
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.
}
}
}
}
这篇关于有界背景和EF代码首先 - 如何把它们放在一起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!