5

古いアプリケーションで作成および管理されている SQL サーバー データベースで動作する C# アプリケーションを作成する必要があります。アプリケーションは毎年新しいテーブルを作成し、「年プロパティ」がテーブル名に含まれています。作成されるテーブルの数は、ユーザーがアプリケーション内で作成した「セクション」の数によって異なります。そのため、Cwx_DRyz のようなテーブルを使用する必要があります (自明です...)。ここで、"wx" はセクション、"yz" は年になります。テーブルのグループの例は次のとおりです。

C01_DR07

C01_DR08

C01_DR09

C02_DR08

C02_DR09

C03_DR06

C04_DR12

これらのテーブルはすべて、たとえばクライアントを表すことができます。部門も年も違うクライアントですが、構造は同じです。

私の質問は次のとおりです。これらすべてのテーブルを処理し、実行時にマッピングを別のテーブルに変更するクライアント エンティティを使用できますか? 実行前のテーブルがわからないため、タイトルは「不明」と表示されています。

私が見つけた最も類似した質問は、Entity Frameworkが複数のテーブルを1つのエンティティにマップすることであり、答えは「具体的な型の継承ごとのテーブル」を使用することですが、私の場合は役に立ちません。

PS: EF バージョン 4.3.1 および VS2010

編集:テーブルには主キーがありません...それらのほとんどには、一意の値(整数または文字列)を持つと想定される列があります。

4

1 に答える 1

4

「コードファースト」を使用すると、必要に応じてマッピングを作成できます。作成したマッピングがデータベースと一致する場合、これは既存のデータベースでも機能します。

したがって、コンテキストを作成するたびに、マップ先の文字列 (テーブル名) を作成できます。

「コードファースト」のコードサンプルと開始方法:

DbContext:

public DbSet<YourEntity> YourEntities { get; set; }
...

// this is called when the db gets created and does the configuration for you => maybe not needed in your case
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    ConfigurationRegistrar configurationRegistrar = modelBuilder.Configurations;

    new GeneralEntitiesConfiguration(configurationRegistrar);
}

GeneralEntitiesConfiguration は、構成を処理するために使用するクラスであり、次のようなヘルパーにすぎません。

public class GeneralEntitiesConfiguration
{
    public GeneralEntitiesConfiguration(ConfigurationRegistrar configurationRegistrar)
    {
        configurationRegistrar.Add(new YourEntityConfiguration());
        //and additional configurations for each entity, just to splitt it a bit and have it more read and maintenance able
    }
}

YourEntityConfiguration は、このエンティティのすべての構成を持つクラスです。

public class YourEntityConfiguration : EntityTypeConfiguration<YourEntity>
{
    public YourEntityConfiguration ()
    {
        ToTable("WhatEverYouLike"); // here you can do any magic to map this entity to a table, just make sure that your properties are mapped to the correct colums
        Property(entity => entity.Id).HasColumnName("YouColumnName");

        //and here you also have to do the other configurations
    }
}

アプリケーションの起動時 (または最初にコンテキストを初期化する前) に、データベースを初期化する必要があります。したがって、データベースをチェックして違いを処理する初期化子を使用できます。"DropCreateDatabaseAlways" や "DropCreateDatabaseIfModelChanges" のようなものが組み込まれています => 違いを無視する独自のものを作成する必要があります。私のサンプルでは、​​モデルが異なる場合に例外をスローするものを作成しました(最初の試行でモデルの変更をsciptsで処理したかったのです):

//before using the context the first time i'm calling, you can ignore the connection string
DbContextInitializer.Init(conString);

public static class DbContextInitializer
{
    public static void Init (string connectionString)
    {
        Database.SetInitializer(new CreateDbThrowExceptionIfModelDiffersInitializer<SMDbContext>());

        using(var dbContenxt = new MyDbContext(connectionString))
        {
            try
            {
                dbContenxt.Database.Initialize(true);
            }
            catch(DatabaseModelDiffersException diffException)
            {
                // some magic...
            }
            catch(Exception ex)
            {
                // TODO: log
                throw;
            }
        }
    }

    public class CreateDbThrowExceptionIfModelDiffersInitializer<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
    {
        public void InitializeDatabase(TContext context)
        {
            using (new TransactionScope(TransactionScopeOption.Suppress))
            {
                if (!context.Database.Exists())
                    context.Database.Create();
            }

            if (!context.Database.CompatibleWithModel(true))
            {
                throw new DatabaseModelDiffersException("Database Model differs!");
            }
        }

        protected virtual void Seed(TContext context)
        {
            // create data if you like
        }
    }

    // just an exception i'm using for later useage
    public class DatabaseModelDiffersException : Exception
    {
        public DatabaseModelDiffersException(string msg) : base(msg)
        {}
    }
}

エンティティ フレームワークを使用して動的なテーブル名を処理できることを理解していただければ幸いです。さらに質問がある場合は、質問してください ;)

于 2012-06-21T16:28:18.460 に答える