0

私が理解しているように、接続文字列は1つのクラスにのみ関連付けられています。しかし、Model クラスが多数ある場合はどうなるでしょうか。1 つの接続文字列を複数のクラスに使用できますか?

これは、私の UserModel.cs ファイルの単純なバージョンです。

public class UserModel
{
    public int Id { get; set; }
    public string Email { get; set; }
}

public class UserTable : DbContext
{    
    public UserModel GetByEmail(string Email)
    {    
        return this.Database.SqlQuery<UserModel>("SELECT * FROM Users WHERE Email=@Email", new SqlParameter("Email", Email)).SingleOrDefault();    
    }
}

そして、これは接続文字列です:

<connectionStrings>
    <add name="UserModel"
         connectionString="Server=.\SQLEXPRESS;Database=MyDatabase;User Id=MyUser;Password=MyPassword;"
         providerName="System.Data.SqlClient" />
</connectionStrings>

ここで、ユーザー テーブルと同様に DbContext から派生した DataTable という名前の新しいモデル クラスを追加するとします。同じ名前の接続文字列が必要ですか、それとも既に定義されているものを使用できますか? 複数のモデル クラスと接続文字列を処理する従来の方法は何ですか?

4

2 に答える 2

1

DbContext クラスは、ConnectionString を使用してデータベースへの接続を確立します。

通常、DbContext によって公開される複数のモデル クラスがあります。

同じ接続文字列値を使用してデータベースに接続する複数の DbContext オブジェクトを持つことができます。このようにして、必要に応じて、モデルの一部を個別のコンテキストに分けることができます (たとえば、異なるテーブルにアクセスするがアプリケーションに同様のサービスを提供する個別のアセンブリを作成する場合)。

少なくとも 5.0 までの EF で注意すべき点が 1 つあります。複数の DbContext でコード ファーストの移行を使用することはできません。一方が他方の変更を上書きします。これに対する解決策は、移行プロセスにのみ使用される集約された DbContext を作成することです。

私が作成したアプリでこれを行いました。Unity IoC コンテナーを使用し、プラグイン インターフェイスを構築して、ConnectionStringName を分離した DbContext に渡すことができるようにしました。アセンブリの 1 つのプラグインの例は次のとおりです。

public class Bootstrapper : IBootstrapper
{
    public void Bootstrap(IUnityContainer container, string connectionStringName)
    {
        container.RegisterType<ISQService, SQService>();
        container.RegisterType<ISQEntities, SQEntities>(
            new HierarchicalLifetimeManager(), new InjectionConstructor(connectionStringName));
        container.RegisterType<IController, SQController>("SQ");
    }
}

私の global.asax は、以下のブートストラップ クラスを参照しました。

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        ModelBinders.Binders[typeof(DataTable)] = new DataTableModelBinder();
        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        Bootstrapper.Initialise();
    }

    protected void Application_End()
    {
        Bootstrapper.Dispose();
    }

ブートストラップ

public static class Bootstrapper
{
    private static IUnityContainer container;

    public static void Initialise()
    {
        container = BuildUnityContainer();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }

    public static void Dispose()
    {
        container.Dispose();                
    }

    private static void RegisterPlugins(IUnityContainer theContainer, string wildcard, string connectionStringName)
    {
        var pluginBootStrappers = from Assembly assembly in wildcard.LoadAssemblies()
                                  from type in assembly.GetExportedTypes()
                                  where typeof(IBootstrapper).IsAssignableFrom(type)
                                  select (IBootstrapper)Activator.CreateInstance(type);

        pluginBootStrappers.ToList().ForEach(b => b.Bootstrap(theContainer, connectionStringName));
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var theContainer = new UnityContainer();
        const string ConnectionStringName = "MyDb";

        RegisterPlugins(theContainer, "MyApp.Systems.*.dll", ConnectionStringName);

        // Register Application Specific objects
        theContainer.RegisterType<IMyEntities, MyEntities>(
            new HierarchicalLifetimeManager(), 
            new InjectionConstructor(ConnectionStringName));

        theContainer.RegisterType<IAimaService, AimaService>();

        var factory = new UnityControllerFactory(theContainer);
        ControllerBuilder.Current.SetControllerFactory(factory);

        return theContainer;
    }
}
于 2013-03-03T13:10:52.227 に答える
0

接続文字列は、DB への接続に必要なパラメーターを定義します。

たぶん、SQLクエリと接続文字列について話しているか、混同していると思います。

はい、1 つの SQL クエリで、いつでも複数のテーブルをクエリできます。詳細については、Google の「SQL クエリ ステートメント」を参照してください。

于 2013-03-03T12:16:31.573 に答える