有界背景和EF代码首先 - 如何把它们放在一起? [英] Bounded Contexts and EF Code First - How to put them together?

查看:184
本文介绍了有界背景和EF代码首先 - 如何把它们放在一起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

IM HO IM HO。。。。。。。。。。。。。。。。。。。。。。。但是我很困惑我如何把所有的东西都合在一起。



首先,我知道有一件事与其他事情无关。但是我的问题完全在基础设施/ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆