首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用实体框架实现读写分离

如何用实体框架实现读写分离
EN

Stack Overflow用户
提问于 2016-03-03 13:30:12
回答 1查看 7.9K关注 0票数 17

我有一个使用“主/从复制”的数据库设置。我有一个主人,(至少)一个奴隶,可能是ℕ奴隶。为了简单起见,从现在开始,我将讨论一个主、一个从,因为确定要使用哪个从属程序包括一些与实际问题无关的业务逻辑。

下面是设置的原理图(使用ℕ从站):

在应用程序(目前正在使用脱衣舞)中,我有以下简化的代码:

代码语言:javascript
复制
abstract class BaseRepo
{
    private readonly string _readconn;
    private readonly string _writeconn;

    public BaseRepo(string readConnection, string writeConnection)
    {
        _readconn = readConnection;     //Actually IEnumerable<string> for ℕ slaves
        _writeconn = writeConnection;
    }

    private SqlConnection GetOpenConnection(string cnstring)
    {
        var c = new SqlConnection(cnstring);
        c.Open();
        return c;
    }

    public SqlConnection GetOpenReadConnection()
    {
        return this.GetOpenConnection(_readconn);
        // Actually we use some business-logic to determine *which* of the slaves to use
    }

    public SqlConnection GetOpenWriteConnection()
    {
        return this.GetOpenConnection(_writeconn);
    }
}

class CustomerRepo : BaseRepo
{
    // ...ctor left out for brevity...

    // "Read" functions use the "read" connection
    public IEnumerable<Customer> ListCustomers()
    {
        using (var c = this.GetOpenReadConnection())
        {
            return c.Query<Customer>("select * from customers order by name");
        }
    }

    // "Write" functions use the "write" connection
    public void UpdateCustomer(Customer cust)
    {
        using (var c = this.GetOpenWriteConnection())
        {
            c.Execute("update customers set name = @name where id = @id", cust);
        }
    }
}

我的问题是:假设我想使用实体框架(如果是相关的话,“代码优先”),而不是Dapper;我如何才能最好地实现相同的概念;插入/更新/删除是针对“主”数据库执行的,而选择是针对从(或任何从服务器)执行的。EF完全支持这种情况吗?我需要做些什么才能让这件事成功?

附加信息:我已经使用Server级别的“只读”和“只写”用户作为“最后一道防线”,以防止DAL中的任何错误。我正在寻找的是一种限制DAL的方法,以避免因为“不允许”操作而不得不捕获Server异常,并且必须首先转到(不正确的) SQL服务器,然后才能找到所需的操作。我可以使用与现在相同的方法;在方法本身中实例化/使用正确的DbContext (在上面的示例中是listcustomers/updatecustomer)。我明白了。但这意味着我必须为每个“实体”上的每个"CRUD“操作创建一个‘包装器’函数,这也是我从dapper迁移到EF的原因之一;简单地公开一个DBSet,让EF处理转换跟踪/SQL查询等等,现在,希望也能找到每个操作要使用的连接字符串。

EN

回答 1

Stack Overflow用户

发布于 2016-04-28 09:54:56

按照其他人的建议,默认情况下创建一个读/写上下文,然后创建一个继承它的只读上下文。如果您也愿意的话,也要确保在分部类中实现接受另一个配置的构造函数。

代码语言:javascript
复制
public partial class CustomerEntities : DbContext
{
    protected CustomerEntities(string nameOrConnectionString):base(nameOrConnectionString)
    {         
    }
}

public class ReadonlyCustomerEntities : CustomerEntities
{
    public ReadonlyCustomerEntities ()
        : base("name=ReadonlyCustomerEntities")
    {          
    }

    public override int SaveChanges()
    {
        // Throw if they try to call this
        throw new InvalidOperationException("This context is read-only.");
    }
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35773560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档