Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何管理共享表与可自定义表_C#_Sql Server_Linq To Sql_Views - Fatal编程技术网

C# 如何管理共享表与可自定义表

C# 如何管理共享表与可自定义表,c#,sql-server,linq-to-sql,views,C#,Sql Server,Linq To Sql,Views,我们有许多客户机在使用我们的应用程序,每个客户机在我们的MS SQL Server上都有自己的、结构相同的数据库。我们还有一个中央数据库,用于存储不变的信息,因此在所有客户端之间共享,例如USPS邮政编码数据库。每个客户端数据库都有这些表的视图,如下所示: create view V_ZIPCode as select ID, ZIP, City, State from SharedDB..ZIPCode 客户端无权修改SharedDB中的数据 但是,有些表中的数据大部分是共享的,但是客户机可

我们有许多客户机在使用我们的应用程序,每个客户机在我们的MS SQL Server上都有自己的、结构相同的数据库。我们还有一个中央数据库,用于存储不变的信息,因此在所有客户端之间共享,例如USPS邮政编码数据库。每个客户端数据库都有这些表的视图,如下所示:

create view V_ZIPCode as
select ID, ZIP, City, State
from SharedDB..ZIPCode
客户端无权修改SharedDB中的数据

但是,有些表中的数据大部分是共享的,但是客户机可能希望添加一些自己的记录

所以我想知道如何最好地实施这种情况

我可以把表放在客户机数据库中,并用共享记录预先填充每个客户机——但这似乎过于繁重和不雅。当然,如果出于任何原因更新了共享记录,更改不会自动传播到客户端;我必须将数据复制到所有的客户机数据库,这非常糟糕

我的另一个想法是在SharedDB和客户端DB中创建相同的表,然后在客户端DB上创建一个视图,如下所示:

create view V_MyTable as
select ID, Description, convert(bit, 0) IsClientData from SharedDB..MyTable
union
select ID, Description, 1 from MyTable
为了防止ID重复,我可以在客户机表上以非常高的数字(比如1000000)为标识值设定种子(比我在中央数据库中使用的还要多;这些是非常稳定的查找值);我不确定是否需要该
IsClientData
字段,但这只是一个小细节。客户机可以使用视图选择他们想要的任何内容,但他们只能在自己的数据库中修改表上的数据

这种方法有两个缺点,我可以看到:一方面,我不能在引用此视图的任何表上使用外键,但我想任何对不同数据库的引用都是如此。另一个问题是,我不确定该视图在查询中的效率

你能看到这种方法会带来的其他问题吗?你能推荐一些优化吗?或者你会推荐一种完全不同的方法吗

如果有什么不同的话,应用程序的业务层是用C#编写的,使用Linq to Sql。

除非(如您所说)在整个系统中传播数据,否则对我来说它看起来非常可靠

下面是将所有数据存储在一个中心位置的方法的概要。你必须充实一些,制定出命名约定和可更新的视图皱纹等等。我认为它很优雅,但优雅可能被高估了

--  In SharedDB
CREATE TABLE CentralTable
 (
   Id              int           not null  identity(1000000, 1)
  ,OwningClientDB  sysname       null
  ,YourDataHere    varchar(100)  not null
  --  Toss in stuff like who added it, when it was added, etc.)
 )
正如您所提到的,所有公共数据都是通过SET IDENTITY_INSERT CentralTable ON添加的,Id值小于1000000,拥有的ClientDB为null。然后,在每个客户机数据库中:

--  In client DB
CREATE VIEW vCentralTable (Id, OwningClientDB, YourDataHere, etc.) as
 select Id, OwningClientDB, YourDataHere, etc.
  from SharedDB.dbo.CentralTable
  where isnull(OwningClientDB, db_name()) = db_name()
该视图过滤出给定客户端可以看到的行。我根据数据库名称进行筛选,但可能有更有效的方法,这取决于您如何识别“拥有”客户端。

除非(如您所说)在整个系统中传播数据,否则对我来说这似乎非常可靠

下面是将所有数据存储在一个中心位置的方法的概要。你必须充实一些,制定出命名约定和可更新的视图皱纹等等。我认为它很优雅,但优雅可能被高估了

--  In SharedDB
CREATE TABLE CentralTable
 (
   Id              int           not null  identity(1000000, 1)
  ,OwningClientDB  sysname       null
  ,YourDataHere    varchar(100)  not null
  --  Toss in stuff like who added it, when it was added, etc.)
 )
正如您所提到的,所有公共数据都是通过SET IDENTITY_INSERT CentralTable ON添加的,Id值小于1000000,拥有的ClientDB为null。然后,在每个客户机数据库中:

--  In client DB
CREATE VIEW vCentralTable (Id, OwningClientDB, YourDataHere, etc.) as
 select Id, OwningClientDB, YourDataHere, etc.
  from SharedDB.dbo.CentralTable
  where isnull(OwningClientDB, db_name()) = db_name()

该视图过滤出给定客户端可以看到的行。我根据数据库名称进行筛选,但可能有更有效的方法,这取决于您如何识别“拥有”客户端。

这是一个有趣的想法,它适用于创建和读取,但在更新和删除时会产生一些小问题。您必须能够更新和删除客户端数据,但不能更新和删除共享数据。将它们全部放在同一个物理表上不会让实现变得非常困难吗?如果基于客户端的数据发生了很大的变化(插入、更新、删除),那么是的,它会变得很困难。如果我做了这样的事情(这主要是一个“思维实验”),我会研究视图上的触发器,而不是触发器。嗯,变得丑陋…可能只有在数据必须位于一个位置时才值得做,例如出于业务逻辑或FK原因。有趣的想法,它适用于创建和读取,但在更新和删除时会产生一个小问题。您必须能够更新和删除客户端数据,但不是共享数据。将它们都放在同一个物理表上不是会让实现变得非常困难吗?如果基于客户端的数据变化很大(插入、更新、删除),那么是的,它会变得很困难。如果我使用类似的方法(这主要是一个“思维实验”),我会研究视图上的触发器,而不是触发器。嗯,变得丑陋…可能只有在数据必须位于一个位置时才值得做,例如出于业务逻辑或FK原因。