加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何通过实体框架实现读/写分离

发布时间:2020-12-15 03:46:14 所属栏目:百科 来源:网络整理
导读:我有一个使用“主/从复制”的数据库设置.我有一个主人(至少)一个奴隶,可能是奴隶.为了简单起见,我将讨论一个主人,一个奴隶,因为确定使用哪个从属机包括一些与实际问题无关的业务逻辑. 这是一个设置的原理图(带?从站): 在应用程序(目前使用Dapper)中,我有以
我有一个使用“主/从复制”的数据库设置.我有一个主人(至少)一个奴隶,可能是奴隶.为了简单起见,我将讨论一个主人,一个奴隶,因为确定使用哪个从属机包括一些与实际问题无关的业务逻辑.

这是一个设置的原理图(带?从站):

在应用程序(目前使用Dapper)中,我有以下简化代码:

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")
                    .AsEnumerable();
        }
    }

    // "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是否支持这种情况?我需要做什么才能使这项工作?

附加信息:我已经在SQL Server级使用’只读’和’只写’用户作为’最后一道防线’来防止DAL中的任何错误.我正在寻找的是一种限制我的DAL的方法,以避免由于“不允许”操作而必须捕获SQL Server异常,并且必须首先访问(不正确的)SQL服务器,才能找到所需的操作不允许.我可以像现在一样使用相同的方法;在方法本身中实例化/使用正确的DbContext(上述示例中的listcustomers / updatecustomer).我明白了.但是这意味着我必须为每个“实体”上的每个“CRUD”操作创建一个“包装器”功能,这就是为什么我从dapper转移到EF首先;简单地暴露一个DBSet,并让EF处理更改/ SQL查询等等,现在,希望还可以找出每个操作要使用的连接字符串.

解决方法

根据其他人的建议,默认情况下创建一个读/写上下文,然后创建一个从它继承的只读方式.
还要确保在部分类中实现一个构造函数,如果你也愿意接受另一个配置.
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.");
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读