Entity Framework和SQL Server同义词的Code First

12

我有这样的情况,将会有多个公司访问我的应用程序的单个实例,但我需要隔离它们的数据以避免意外加载另一个公司的数据,并且便于每个公司的数据库备份。

理想情况下,我希望按照以下方式将数据拆分成不同的数据库:

  • 一个SQL Server数据库用于所有用户的列表,以及任何在所有用户/公司之间共享的表

  • N个特定于公司的数据库,每个数据库具有相同的模式,但每个公司的数据不同。 登录时,我将动态选择特定用户公司的数据库

我想能够查询公司特定数据表,但是在共享数据库上执行联接(例如,这样我可以将外键存储在公司数据库表中,它连接到其他数据库中共享表的主键)。

我发现了SQL Server Synonyms,看起来它们可以完成这项工作,而且似乎我可以使用SQL Server Management Studio中的查询在两个数据库之间进行连接。

是否可能在Entity Framework Code First中使用Synonym表? 如果可能,我的POCO类/DbContext需要什么样子?

谢谢 :)


无论您是否使用同义词,都无法在数据库之间创建外键,因此我不认为它们能够“胜任工作”。请参见:https://dev59.com/w3M_5IYBdhLWcg3wUxfF 如果您不需要显式的外键关系,则可以将本地表连接到centraldatabase.dbo.table,而不是在各个地方创建同义词。或者EF根本不允许跨数据库连接吗? - Aaron Bertrand
3
据我所知,如果您的项目不符合EF/CF模型的严格参数,这并不是您会遇到的最后一个限制。EF/CF是你必须使用的吗?还是因为它很流行才使用它?我怀疑,如果您想要做任何稍微复杂一点的事情,您很快就会对其所有限制感到沮丧,并寻求其他替代方案。 - Aaron Bertrand
1
你有没有考虑过创建视图,将共享数据库中的数据暴露给客户特定的数据库(通过客户特定的数据库)? - Pawel
@AaronBertrand - 评论很中肯,从我的经验来看,我倾向于同意。我们不需要在这个项目中使用EF,但觉得尝试一下是值得的。它似乎有它的优点和缺点 - 我喜欢它消除了编写成千上万行CRUD的要求,处理与域对象的映射,并且使用LINQ查询很棒(特别是它获取分层结果的能力)。但我不喜欢它的魔法数量/失去控制。同时也在尝试http://www.telerik.com/products/orm.aspx,它似乎有更好的工具。 - Matt Wilson
我之前不知道这个文档,但基本上这就是我的意思。EF支持视图,所以这可能是可行的方法。EF不支持多个数据库,但你可以使用视图将每个数据库中共同的数据公开为一个表。 - Pawel
显示剩余3条评论
1个回答

9
如果我理解正确,你有一个SharedServer和一些LocalServers(公司特定),它们想要在单个上下文中拥有两个对象的所有内容(一个是共享的,一个是公司特定的)。
我将给您两种情况:
1. 多对多:在这种情况下,需要关联表的表位于sharedDB中,但是连接它们的第三个表位于公司特定DB中。 2. 单对多:其中一个表位于SharedDB中,另一个表位于公司特定DB中。

Many-to-Many

1. 在SQL侧创建同义词

首先,您必须在本地(或公司特定)数据库中创建同义词:
CREATE SYNONYM [dbo].[StudentCources] FOR [SharedServer].[SharedDB].[dbo].[StudentCources]

假设你的共享表有两列(不要在意)分别叫做 studentIDcourseID

2. 创建 POCOs

假设我们有两个本地数据库上的表,它们之间存在多对多关系。让我们假设第三个连接表(包含键)位于共享数据库中!!(我认为这是最糟糕的方式)。因此,你的 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总是为空,即使数据库中有数据(当我使用不同的context获取数据时,我没有遇到这个问题)。你知道这方面的任何信息吗? - levininja
1
请问您能否详细解释一下? - Hamed Zakery Miab
1
运行得非常好。我想指出,我不得不伪造迁移,而实际上并没有创建表。 - MetalGeorge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接