2013-08-07 26 views
2

我们正在构建一个将出售给客户端的c#.Net应用程序,SQL Server数据库将由我们托管。我们将为每个客户建立一个数据库。我们不确定我们是否可以使用一个WCF数据服务来访问不同的数据库。使用实体框架构建数据库。如何让应用程序通过wcf使用不同的数据库dataservice

我该如何做到这一点,以便客户端可以传入正确的数据库名称或连接字符串?

Different databases using WCF dataservice说这是可能的,但没有真正进入具体情况。

这个WCF Service for Multiple clients with database(each for client)看起来是相同的问题,但没有答案。

+1

避免从客户端接收(甚至暴露)连接字符串的情况。 – Paparazzi

回答

2

使您的WCF服务会话基于,提供一个登录方法,并且在此方法中您必须决定使用哪个数据库,如果DataModel相同或者您拥有相同的数据模型,则可以更改edmx的ConnectionString 为每个客户端创建不同的DataModel,您必须为每个客户端创建一个edmx实例!

这里是一些简单的pseude码,ENTITYID标识Client

用于创建EntityConnectionString看看这个Link

要创建您需要定义服务接口一样,

一个基于会话的WCF服务
[ServiceContract(SessionMode = SessionMode.Required)] 
public interface ISampleService 
{ 
    [OperationContract] 
    void Login(string user, string password, int entityID); 
} 

和ServiceImplementation应具有这些属性,根据您的需要更改这些值

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single, AutomaticSessionShutdown = true)] 
public class SampleService : ISampleService 
{ 
    SampleEntities datacontext = null; 
    public void Login(string user, string password, int entityID) 
    { 
     if(CheckLoginData(user, password)) 
     { 
     InitDataContext(entity_id); 
     } 
    } 
    private void InitDataContext(int entityID) 
    { 
     var connectionString = GetConnectionStringFromEntityID(entityID); 
     datacontext = new SampleEntities(connectionString); 
    } 
    private string GetConnectionStringFromEntityID(int entityID) 
    { 
     var providerName = "System.Data.SqlClient"; 
     var serverName = "localhost"; 
     var databaseName = GetDatabaseNameFromEntityID(entityID); 

     var sqlBuilder = new SqlConnectionStringBuilder(); 
     sqlBuilder.DataSource = serverName; 
     sqlBuilder.InitialCatalog = databaseName; 
     sqlBuilder.IntegratedSecurity = true; 

     var providerString = sqlBuilder.ToString(); 

     var entityBuilder = new EntityConnectionStringBuilder(); 
     entityBuilder.Provider = providerName; 
     entityBuilder.ProviderConnectionString = providerString; 

     entityBuilder.Metadata = @"res://*/SampleDatabase.csdl| 
         res://*/SampleDatabase.ssdl| 
         res://*/SampleDatabase.msl"; 

     return entityBuilder.ToString(); 
    } 
} 
+0

这看起来像我会走的路。 GetConnectionStringFromEntityID可能是什么样子...... –

+0

或者只是使用EntityConnectionStringBuilder链接中的示例更改名称? –

+1

是我完成了从EntityConnectionStringBuilder链接的代码示例!我没有测试过,但它应该以类似的方式工作! – makim

0

我该如何做到这一点,以便客户端可以传入正确的数据库名称或连接字符串?

我诚实地不会给客户端太多的灵活性,它可以使用什么连接字符串。你可以将你的连接字符串存储到一个普通的数据库中,这给了一个用户凭证可以返回一个正确的连接字符串......但是这并不能给我一种温暖和模糊的感觉。

在我看来,如果您打算有很多客户,为每个客户部署一个WCF服务会更有意义。这样它们就与其他客户隔离开来。您仍然可以将它们托管在同一个IIS服务器中,但您可以使用不同的端点。这也将允许您利用WCF提供的不同认证方案。

祝您好运,您的解决方案。

+0

但每个客户的服务不利。 – Paparazzi

+0

@Blam也许我在瞒着我的天真,但这是一个不利的方面呢? –

+0

维护多个服务而不是1.为每个新客户端添加一项新服务。部署具有多个端点的客户端。 – Paparazzi

1

我们做了多年,这一切是关于URL重写,这样

http://the.application/client1/service

http://the.application/client2/service

在内部改写为同一

http://the.application/service

但在同时重写的部分用于查找连接字符串i n客户端代码和连接字符串之间的服务器端映射。

这里存在安全问题,您不希望您的客户随时在数据源之间切换。我们已经通过将客户端代码放入安全cookie的用户数据部分来解决此问题,并且我们会在每次请求时验证Cookie。

相关问题