9

データベース ストレージに Entity Framework コード ファーストを使用して、ここで説明したのと同様のアプローチを使用して、一時的なプロパティを実装したいと考えています。

現在の値を取得するために最適化し、履歴の遅延読み込みを行いたいのですが、上記のリンクのアプローチのように、使用ごとに親エンティティにボイラープレート コードを追加する必要はありません。

現時点では、以下のコードのようなものがあります。慣例により、コードの下に示すデータベース スキーマになります。

これは必要に応じて機能しますが、パフォーマンス上の理由から、現在のプロパティ値を取得するために必要な結合を避けたい (つまり、代わりに TemporalStrings.CurrentValue DB 列を Entities.Name に移動したい)。

私が試したら

modelBuilder.Entity<Entity>().Property(o => o.Name.CurrentValue).HasColumnName("Name");

うまくいきません。次のような例外が発生します

The type 'ConsoleApplication1.TemporalString' has already been configured as an entity type. It cannot be reconfigured as a complex type.

このマッピングを実現する方法はありますか、またはこの機能を実現するためのより良いアプローチはありますか?

コード:

public class TemporalString
{
    public int Id { get; set; }
    public string CurrentValue { get; set; } // Setter would be customized to append to History.
    public virtual List<TemporalStringValue> History { get; set; }
    // Other methods such as string ValueAt(DateTime) would exist.
}

public class TemporalStringValue
{
    public int Id { get; set; }
    public DateTime EffectiveFrom { get; set; }
    public string Value { get; set; }
}

public class Entity
{
    public int Id { get; set; }
    public virtual TemporalString Name { get; set; }
}

public class TestDbContext : DbContext
{
    public DbSet<Entity> Entities { get; set; }
    public DbSet<TemporalString> TemporalStrings { get; set; }
    public DbSet<TemporalStringValue> TemporalStringValues { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //modelBuilder.Entity<Entity>().Property(o => o.Name.CurrentValue).HasColumnName("Name");
        // TODO: Map DB column TemporalStrings.CurrentValue to DB column Entities.Name?
    }
}

internal class Program
{
    private static void Main(string[] args)
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TestDbContext>());
        using (var context = new TestDbContext())
        {
            var entity = new Entity
                             {
                                 Name = new TemporalString
                                            {
                                                CurrentValue = "Current Value",
                                                History = new List<TemporalStringValue>
                                                              {
                                                                  new TemporalStringValue
                                                                      {
                                                                          EffectiveFrom = DateTime.UtcNow,
                                                                          Value = "Current Value"
                                                                      },
                                                                  new TemporalStringValue
                                                                      {
                                                                          EffectiveFrom = DateTime.UtcNow.AddMonths(-1),
                                                                          Value = "Old Value"
                                                                      },
                                                                  new TemporalStringValue
                                                                      {
                                                                          EffectiveFrom = DateTime.UtcNow.AddMonths(-2),
                                                                          Value = "Older Value"
                                                                      }
                                                              }
                                            }
                             };
            context.Entities.Add(entity);
            context.SaveChanges();
        }
        Console.Write("Done.");
        Console.ReadKey();
    }
}

結果のスキーマ:

Entities
(PK) Id
(FK) Name_Id (references TemporalStrings.Id)

TemporalStrings
(PK) Id
     CurrentValue

TemporalStringValues
(PK) Id
     EffectiveFrom
     Value
(FK) TemporalString_Id

望ましいスキーマ:

Entities
(PK) Id
(FK) Name_Id (references TemporalStrings.Id)
     Name (formerly TemporalStrings.CurrentValue)

TemporalStrings
(PK) Id

TemporalStringValues
(no change)
4

0 に答える 0