2

我们正在构建将出售给客户的 ac# .Net 应用程序,SQL Server 数据库将由我们托管。我们将为每个客户提供一个数据库。我们不确定是否可以使用一种 WCF 数据服务来访问不同的数据库。使用实体框架构建数据库。

我怎样才能做到这一点,以便客户端可以传递正确的数据库名称或连接字符串?

This Different databases using WCF dataservice说这是可能的,但并没有真正进入细节。

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

4

3 回答 3

2

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

这里有一些简单的伪代码,entityID 标识了客户端

要创建 EntityConnectionString,请查看此链接

要创建基于会话的 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();
    }
}
于 2013-08-07T17:30:02.253 回答
1

我们已经做了很多年了,这一切都与 url 重写有关

http://the.application/client1/service

http://the.application/client2/service

在内部重写为相同的

http://the.application/service

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

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

于 2013-08-07T20:15:39.323 回答
0

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

老实说,我不会给客户太多的灵活性来决定它可以使用什么连接字符串。您可以将连接字符串存储到公共数据库中,给定用户凭据可以返回正确的连接字符串......但这并没有给我一种温暖和模糊的感觉。

在我看来,如果您计划拥有大量客户,那么为每个客户部署 WCF 服务会更有意义。这样他们就与您的其他客户隔离了。您仍然可以将它们托管在同一 IIS 服务器中,但您可以使用不同的端点。这也将允许您利用 WCF 提供的不同身份验证方案。

祝你的解决方案好运。

于 2013-08-07T17:54:09.683 回答