同じスキーマの50個のデータベースをホストするサーバーがあり、次のバージョンでEntity Frameworkの使用を開始したいと考えています。
これらのデータベースごとに新しい接続は必要ありません。 1つの接続の権限で50のデータベースすべてと通信できます。データ管理と速度のために(これはWebAPIアプリケーションです)、各データベースと通信するたびに新しいEFコンテキストをインスタンス化したくありません。もちろん、リクエストがサーバーに来るたびにこれが発生する場合を除いて、その必要はありません。
私が本当に必要なのは、USE [データベース名]コマンドを変更する機能だけです。これは、最終的にEFからサーバーに送信されると想定しています。
コードでこれを達成する方法はありますか? EFは、SaveChanges()などを呼び出す前にオンザフライで変更される可能性のあるデータベース名を参照する、読み取り/書き込みプロパティをコンテキストに保持していますか?
ありがとうございました!!!
ボブ
あなたは見てみることができます:
さらにサポートが必要な場合はお知らせください。
編集済み
2番目のリンクが SqlConnection.ChangeDatabase メソッドを指すように更新されました。
最終的に、コードは次のようになります。
MetadataWorkspace workspace = new MetadataWorkspace(
new string[] { "res://*/" },
new Assembly[] { Assembly.GetExecutingAssembly() });
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
using (EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection))
using (NorthwindEntities context = new NorthwindEntities(entityConnection))
{
// do whatever on default database
foreach (var product in context.Products)
{
Console.WriteLine(product.ProductName);
}
// switch database
sqlConnection.ChangeDatabase("Northwind");
Console.WriteLine("Database: {0}", connection.Database);
}
一生懸命働かないで、賢く働け!!!!
MYContext localhostContext = new MYContext();
MYContext LiveContext = new MYContext();
//If your databases in different servers
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("localhost", "Live");
//If your databases have different Names
LiveContext.Database.Connection.ConnectionString = LiveContext.Database.Connection.ConnectionString.Replace("DBName-Localhost", "DBName-Live");
データベースの構造は同じでなければなりません;)
とてもシンプルです
持っていた
public WMSEntities() : base("name=WMSEntities") //WMSEntities is conection string name in web.config also the name of EntityFramework
{
}
edmxフォルダーの自動生成されたModel.Context.csに既にあります。
ランタイムで複数のデータベースに接続するために、同じファイルModel.Context.csに以下のような接続文字列をパラメーターとして受け取る別のコンストラクターを作成しました
public WMSEntities(string connStringName)
: base("name=" + connStringName)
{
}
今、私は例えばWeb.Configに他の接続文字列を追加しました
<add name="WMSEntities31" connectionString="data source=TESTDBSERVER_NAME;initial catalog=TESTDB;userid=TestUser;password=TestUserPW/>
<add name="WMSEntities" connectionString="data source=TESTDBSERVER_NAME12;initial catalog=TESTDB12;userid=TestUser12;password=TestUserPW12/>
次に、データベースに接続するときに、以下のメソッドを呼び出して、パラメーターとしてconnectionString名を渡します
public static List<v_POVendor> GetPOVendorList(string connectionStringName)
{
using (WMSEntities db = new WMSEntities(connectionStringName))
{
vendorList = db.v_POVendor.ToList();
}
}
これがデータベース名を変更するための私の解決策です。 Webまたはapp.configファイルから文字列をプルし、変更して、インスタンス化するだけです。
string yourConnection = ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString.Replace("MyDatabase", yourDatabaseName);
dcon = new MyEntities(yourConnection);
EntityConnection.ChangeDatabaseメソッドはサポートされていませんが、SqlConnection.ChangeDatabaseは正常に機能します。
したがって、エンティティフレームワークデータベースのコンストラクタでSqlConnectionを使用する必要があります。
using MvcMyDefaultDatabase.Models;
using System.Data.Metadata.Edm;
using System.Data.SqlClient;
using System.Data.EntityClient;
using System.Configuration;
using System.Reflection;
public ActionResult List(string Schema)
{
SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
MetadataWorkspace workspace = new MetadataWorkspace(new string[] { "res://*/" }, new Assembly[] { Assembly.GetExecutingAssembly() });
EntityConnection entityConnection = new EntityConnection(workspace, sqlConnection);
sqlConnection.Open();
sqlConnection.ChangeDatabase(Schema);
Models.MyEntities db = new MyEntities(entityConnection);
List<MyTableRecords> MyTableRecordsList = db.MyTableRecords.ToList();
return View(MyTableRecordsList);
}
このコードを使用すると、「スキーマ」文字列でデータベース名を渡すいくつかのスキーマの同じ形式(同じテーブル名と同じフィールド)でテーブルを読み取ることができます。
これを現在のプロジェクトに実装しました。プロジェクトには、共通のセキュリティデータベースとクライアントごとに異なるデータベースがあります。したがって、セキュリティデータベースには、他のすべてのデータベースの接続文字列を含むテーブルがあります。クライアントIDを渡して、クライアントデータベースの接続文字列を取得するだけです。
これには、2つのEDMXを追加して、1つを共通データベース用、もう1つを共通スキーマデータベース用にします。ユーザーがログインするとき、またはデータベースを選択するためのシナリオは何か、共通データベースに移動して接続文字列を取得し、必要なデータベースのオブジェクトを作成します。質問がある場合は、ここにコードサンプルがあります。
他のすべてのデータベースが共有する共通データベースのテーブルに、他のすべてのデータベースに関する接続文字列を保持できます。
EntityInstance_ReviewEntities.GetContext(GetConnectionString(ClientId));
private string GetConnectionString(int TenantId)
{
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
ISecurityRepository objSecurity = new SecurityRepository();
string tenantConnectionString = objSecurity.GetClientConnectionString(TenantId);
entityBuilder.ProviderConnectionString = tenantConnectionString;
entityBuilder.Provider = "System.Data.SqlClient";
entityBuilder.Metadata = @"res://*/ClientEntity.YourEntity.csdl|res://*/ClientEntity.ADBClientEntity.ssdl|res://*/ClientEntity.YourEntity.msl";
return entityBuilder.ToString();
}