实体框架代码优先与 SQL Server 同义词

Posted

技术标签:

【中文标题】实体框架代码优先与 SQL Server 同义词【英文标题】:Entity Framework Code First with SQL Server Synonyms 【发布时间】:2013-01-21 16:53:35 【问题描述】:

我有多个公司访问我的应用程序的单个实例的情况,但我需要隔离他们的数据以避免意外加载另一家公司的数据,并简化每个公司的数据库备份。

理想情况下,我想将数据拆分到不同的数据库中,如下所示:

一个 SQL Server 数据库,用于列出所有用户,以及 所有用户/公司通用的任何表格

N 个公司特定数据库,每个数据库具有相同的架构,但每个公司的数据不同。登录时,我会为特定用户的公司动态选择数据库

我希望能够查询公司特定的数据表,但要对共享数据库执行连接(例如,我可以在公司数据库表中存储一个外键,它连接到一个其他数据库中的共享表)。

我发现了看起来可以完成这项工作的 SQL Server 同义词,而且我似乎可以通过使用 SQL Server Management Studio 中的查询成功地连接两个数据库。

是否可以在 Entity Framework Code First 中使用同义词表,如果可以,我的 POCO 类/DbContext 需要是什么样的?

谢谢:)

【问题讨论】:

无论您是否使用同义词,您都无法在数据库之间创建外键,所以我不相信他们可以“完成这项工作”。请参阅:***.com/questions/1424327/… 如果您不需要显式的外键关系,那么您不能将本地表加入到centraldatabase.dbo.table,而不是到处创建同义词吗?或者 EF 根本不允许你跨数据库加入? 我没有意识到您可以在没有同义词的情况下直接连接两个数据库 - 我以前从未需要过,但这很有用。关于不能使用外键的一个公平点,我想这永远不会奏效 - 但即使没有明确的关系,如果我能让 EF 支持这一点,它仍然可能是一种前进的方式。据我所知,代码优先 EF 仅支持单个数据库连接,并且将同义词作为表引用是行不通的。 据我所知,如果您的项目不符合该模型的严格参数,这不是您遇到的最后一个 EF/CF 限制。 EF/CF 是您必须使用的东西,还是因为它“风靡一时”而使用它?我怀疑如果你想做任何适度复杂的事情,你很快就会对它的所有界限感到沮丧并寻求其他选择。 您是否考虑过将共享数据库中的数据暴露给(并通过)客户特定数据库的视图? @AaronBertrand - Fair cmets,从我目前的经验来看,我倾向于同意。我们不需要在这个项目中使用 EF,但觉得这是一个值得尝试的练习。似乎有它的优点和缺点 - 我喜欢它如何消除编写数千行 CRUD 的要求,处理与域对象之间的映射,以及使用 LINQ 进行查询很棒(尤其是它能够获取分层结果) .但我不喜欢魔法/失去控制的数量。还尝试了telerik.com/products/orm.aspx,它似乎有更好的工具。 【参考方案1】:

如果我理解正确,您有一个 SharedServer 和一些 LocalServers(特定于公司),它们希望拥有两者的所有对象(一个共享,一个公司特定)在一个单一的上下文中。

我给你两个场景:

    多对多:在这种情况下,有关系的表在 sharedDB 中,但加入它们的第三个表在 公司特定数据库 >. 单对多:哪一张表在SharedDB中,另一张在公司特定数据库中。

多对多

1。在 SQL 端创建您的同义词

首先,您必须在本地(或公司特定)数据库中创建同义词:

CREATE SYNONYM [dbo].[StudentCources] FOR [SharedServer].[SharedDB].[dbo].[StudentCources]

假设您的共享表有两列(无关紧要),分别名为 studentIDcourseID

2。创建 POCO

假设我们在本地数据库中有两个表,它们之间具有多对多关系。让我们假设第三个连接器表(包含键)位于共享数据库中! (我认为这是最糟糕的方式)。所以你的 POCO 看起来像这样:

Public Class Student
    Public Property studentID as Integer
    Public Property Name as String
    Public Property Courses as ICollection(Of Course)
End Class

Public Class Course
    Public Property courseID as Integer
    Public Property Name as String
    Public Property Students as ICollection(Of Student)
End Class

共享之一:

Public Class StudentCources
    Public Property courseID as Integer
    Public Property studentID as Integer
End Class

上下文看起来像:

Partial Public Class LocalContext
    Inherits DbContext

    Public Sub New()
        MyBase.New("name=LocalContext")        
    End Sub

    Public Overridable Property Students As DbSet(Of Student)
    Public Overridable Property Courses As DbSet(Of Course)

    Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)
        modelBuilder.Entity(Of Student).HasMany(Function(e) e.Courses).WithMany(Function(e) e.Students).Map(Sub(e)
            e.MapLeftKey("studentID")
            e.MapRightKey("courseID")
            e.ToTable("StudentCources", "dbo")
    End Sub)

    End Sub
End Class

OnModelCreating 中的代码告诉模型构建器关系表是同义词(不是直接的)。我们知道同义词在 SharedDB 中。

一对多

没有步骤!只需将OnModelCreating 修改为:

modelBuilder.Entity(Of Student).ToTable("Students", "dbo")

请注意,在这种情况下,Students 是一个同义词。然后创建关系:)

【讨论】:

我正在为一对多执行此操作,它似乎可以工作,但我的 context.Student 总是空的,即使数据库中有数据(当我没有那个问题时我使用不同的上下文来获取数据)。你知道吗? 您能解释一下吗? 就像一个魅力。我想指出的是,我必须在没有实际创建 rable 的情况下伪造迁移。

以上是关于实体框架代码优先与 SQL Server 同义词的主要内容,如果未能解决你的问题,请参考以下文章

如果我们使用实体框架和代码优先方法,是不是可以在给定路径上创建数据库(Sql Server compact)?

使用带有实体框架代码优先和 ASP.NET MVC 3 和 mvc miniprofiler 的 SQL Server CE 时出现问题

使用 SQL Server 数据库和实体框架错误的 Windows 应用程序部署

Entity Framework 6 和 SQL Server CE,代码优先

使用实体框架迁移时 SQL Server 连接抛出异常 - 添加代码片段

如何更改实体框架项目以使用 Microsoft SQL Server