c# - Azure 中跨上下文 LINQ 加入?

标签 c# sql-server entity-framework linq azure

我们目前正在将生产平台迁移到 Azure,因此我需要迁移所有支持工具。以前,我们严重依赖数据适配器和存储过程,其中许多存储过程执行跨数据库联接。

随着我们迁移到 Azure,这些跨数据库联接都无法运行。我尝试将我们的数据适配器移动到 Entity Framework ,但我似乎无法使它们工作。相反,我收到一条错误,指出不允许跨上下文连接。其中许多查询依赖于来自多个数据库的数据,因此我只是想找出实现此操作的最佳方法。

我查看了其他几个要求类似解决方案的问题,但它们似乎都不太适用于我的解决方案。

例如,下面是 SQL 中更简单的查询之一:

USE CustomerDB1234
SELECT DISTINCT u.[UserID]
  ,u.[UserLogin]
  ,u.[UserPhoneNumber]
  ,u.[UserPasswordHash]  
  , ISNULL(gl.[gl_login_name],'* no global login ID') AS [gl_login_name]
  ,gl.[gl_password_hash]
  ,gl.[gl_GUID]
  ,gl.[gl_Email_Validated]
  ,u.[usr_unit_set_id]
  ,oob.[oob_org_id]
FROM [dbo].[User] u WITH (NOLOCK)
LEFT JOIN [dbo].[OrganizationObjectBridge] oob WITH (NOLOCK) ON oob.[oob_object_type_id] = 9 AND oob.[oob_object_id]= u.UserID  
LEFT JOIN [MainServer].[MainDb].[dbo].[GlobalLoginCustomerBridge] glcb WITH (NOLOCK) ON glcb.[glcbr_user_id] = u.UserID
    AND glcb.[glcbr_customer_id] = dbo.efnGetCustomerID()
LEFT JOIN [MainServer].[MainDb].[dbo].[GlobalLogin] gl WITH (NOLOCK) ON gl.[gl_id] = glcb.[glcbr_gl_id]
WHERE ([UserID] = @userID OR @userID IS NULL)
    AND ([UserDisabled] = @isDisabled OR @isDisabled IS NULL)
ORDER BY [gl_login_name]

在 Linq 中,它看起来类似于:

List<User2> userList = new List<User2>();
using (var e = new eContext())
using (var context = new CustomerContext(CustomerID))
{
    var databaseConnections = e.DatabaseConnectionStrings;
    var customer = e.Customers.Select(n => new
    {
        ID = n.CustomerID,
        Name = n.CustomerName,
        Email = n.CustomerEmail,
        Website = n.CustomerWWW,
        Logo = n.CustomerLogo,
        DatabaseConnectionName = databaseConnections.FirstOrDefault(d => d.DatabaseConnectionID == n.DatabaseConnectionID).DatabaseConnectionName,
        DatabaseConnectionString = databaseConnections.FirstOrDefault(d => d.DatabaseConnectionID == n.DatabaseConnectionID).DatabaseConnectionString1,
        AccountNumber = n.CustomerAcctNumber
    }).FirstOrDefault(n => n.ID == CustomerID);

    userList = context.Users
        .Join(e.GlobalLoginCustomerBridges,
            u => u.UserID,
            glcb => glcb.glcbr_user_id,
            (u, glcb) => new { u, glcb })
            .Where(n => n.glcb.glcbr_customer_id == CustomerID)
        .Join(e.GlobalLogins,
            glcb => glcb.glcb.glcbr_gl_id,
            gl => gl.gl_id,
            (glcb, gl) => new { glcb, gl })
        .Join(context.OrganizationObjectBridges,
            glcb => glcb.glcb.u.UserID,
            oob => oob.oob_object_id,
            (glcb,oob) => new {glcb, oob})
            .Where(n=>n.oob.oob_object_type_id == 9)
       .Select(n => new
       {
           ID = n.glcb.glcb.u.UserID,
           GlobalLogin = n.glcb.gl.gl_login_name,
           FirstName = n.glcb.glcb.u.UserFirstName,
           MiddleName = n.glcb.glcb.u.UserMiddleName,
           LastName = n.glcb.glcb.u.UserLastName,
           GUID = n.glcb.gl.gl_GUID,
           UserID = n.glcb.gl.gl_id,
           HasSHA256Hash = n.glcb.gl.gl_password_hash_sha256 == null,
           Customer = customer,
           Organization = context.Organizations
               .Select(o => new
               {
                   ID = o.org_id,
                   Name = o.org_name,
                   ParentID = o.org_parent_id,
                   ExternalID = o.org_external_id,
                   Default = o.org_default,
                   Logo = o.org_logo,
                   URL = o.org_url,
                   PeerGroupID = o.org_peer_grp_id,
                   ExternalInfo = o.org_external_info
               }).Cast<Organization2>().FirstOrDefault(o=>o.ID == n.oob.oob_org_id)
    }).Cast<User2>().ToList();

}

最佳答案

两种方法:

  1. 在内存中的应用程序中执行连接。根据查询的不同,这或多或少是有效的。此外,所需的代码更改范围从小到大。
  2. 将数据库合并在一起。在没有物理原因的情况下拥有许多数据库是一种反模式。数据库不是应用程序模块化的逻辑单元。通过模式或表名前缀进行文档模块化。数据库是部署的物理单元。

第三种方法:在虚拟机中运行 SQL Server。

关于c# - Azure 中跨上下文 LINQ 加入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35556499/

相关文章:

c# - 如何对客户端网络代码进行单元测试?

entity-framework - Entity Framework 管道 : Expression trees to ESQL to SQL?

.net - 生产服务器上的数据库连接错误

c# - 在 ASP.NET MVC 中不使用 IoC/DI、UoW 和存储库模式将逻辑从 Controller 操作移动到 "service layer"

SQL 通过/左连接按组获取最大 n 的所有行

C# 类和对象 : Object contains a single vaue

c# - 结合RFID读写器在arduino中接收USB串口数据

c# - 在 LINQ 查询中对基类使用扩展方法

sql-server - SQL服务器: select the latest comment using the max date

sql - 从合并的连接结果集中消除 NULL 字段