Entity Framework: 実行時に接続文字列を変更する 質問する

Entity Framework: 実行時に接続文字列を変更する 質問する

コードファースト アプローチで Entity Framework 6 を使用し、StructureMap を IoC として使用する ASP.NET MVC アプリケーションがあると仮定します。

また、Unit Of Work パターンも使用します。

ドメインクラス:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

IUnitOfWorkそしてDbContext

public interface IUnitOfWork
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
}
    
public class Sample07Context : DbContext, IUnitOfWork
{
    public DbSet<Product> Products { set; get; }
    
    #region IUnitOfWork Members
    
    public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
    {
        return base.Set<TEntity>();
    }
    
    #endregion
}

サービスクラス内のビジネスロジック:

public interface IProductService 
{
    void AddNewProduct(Product product);
    IList<Product> GetAllProducts();
}

public class ProductService: IProductService 
{
    IUnitOfWork _uow;
    IDbSet<Product> _products;
    
    public ProductService(IUnitOfWork uow) 
    {
        _uow = uow;
        _products = _uow.Set<Product>();
    }

    public void AddNewProduct(Product product) 
    {
        _products.Add(product);
    }

    public IList<Product> GetAllProducts() 
    {
        return _products.Include(x => x.Category).ToList();
    }
}

コントローラにサービスクラスを注入する

public class HomeController : Controller
{
    private IProductService _productService;
    private IUnitOfWork _uow;
        
    public HomeController(IUnitOfWork uow, IProductService productService)
    {
        _productService = productService;
        _uow = uow;
    }
        
    [HttpGet]
    public ActionResult Index()
    {
        var list = _productService.GetAllProducts();
        return View(list);
    }
}

StructureMapapp_start で呼び出す構成:

private static void initStructureMap()
{
    ObjectFactory.Initialize(x =>
    {
        x.For<IUnitOfWork>().HttpContextScoped().Use(() => new Sample07Context());
        x.ForRequestedType<IProductService>().TheDefaultIsConcreteType<EfProductService>();
    });
    
    //Set current Controller factory as StructureMapControllerFactory
    ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
}

単一のデータベースではすべて正常に動作しますが、私のシナリオでは、ユーザーは複数のデータベースを使用できます。つまり、ユーザーは実行時に接続文字列を変更できる必要があります。ユーザーがアプリケーションで作成するプロジェクトごとに個別のデータベースを作成します。ここで問題となるのは、DbContextサービスに を挿入してDbContextから接続文字列を読み取るweb.configため、ユーザーがデータベースを変更したときに に新しい接続文字列を設定できないことですDbContext

何を指示してるんですか?

ベストアンサー1

Database First私の経験では、 EF 6 では モードを使用しました。DbContextを追加すると、以下のように生成されますEntity Data Model

public TestEntities()
            : base("name=TestEntities")
        {
        }

App.Config内の要素TestEntitiesを表しますConnectionString

<connectionStrings>   
<add name="TestEntities" connectionString="..." providerName="System.Data.EntityClient" />
</connectionStrings>

ただし、デフォルトのコードを以下のように変更できます。

public partial class TestEntities : DbContext
    {
        public TestEntities()
            : base("name=TestEntities")
        {
        }

        public TestEntities(string sConnectionString)
            : base(sConnectionString)
        {
        }

...}

したがって、DB 接続を取得するには 2 つのオプションがあります。

  1. デフォルトを使用します。EF は構成ファイル内の接続文字列を見つけます。

  2. 接続文字列を DbContext に渡します。

コードは以下のようになります。

EntityConnection entityConn =DBConnectionHelper.BuildConnection();
using (var db = new TestEntities(entityConn.ConnectionString))
{
....
}

質問についてはHow to build a EntityConnection?MSDN エンティティ接続

参考になれば幸いです。

ありがとう。

おすすめ記事