2

Entity Framework 6 の新しい依存関係パターンを使用してカスタム マッピング ルールを挿入する方法はありますか?

私が使用しているデータベースには、いくつかの列に時刻が保存されていtime(0)ます。

MSDN によるとtimeデータ型は任意の長さの時間ではなく、特定の「 1 日の時間」を定義します。これは、00:00:00.0000000 から 23:59:59.9999999 までの型の範囲によって証明されます。time

ここではすべて順調です。ただし、Entity Framework はそれをプロパティにマップすることを拒否しDateTimeます。

ADO.NET の既定値へのマッピングは、 ( Jon Skeet が指摘したようTimeSpanに)理想とはほど遠いものです。SQL Serverは任意の期間ではなく、AM/PM コンテキストを持っているからです。.NET のフォーマッタには、AM/PM の概念がありません。とは別の問題ドメイン用です。純粋に理想主義的な観点から言えば、私はむしろ常に. 開始点が時刻として固定されているため、これも理にかなっています。timeTimeSpantimeTimeSpantimeDateTime

さらに悪いことに、 と の問題領域が分かれているため、DevExpress の TimeEdit などのコントロールはプロパティにのみバインドされtimeます。と の間で単純に変換される重複したプロパティですべてのエンティティを汚さないようにしたいと考えています。TimeSpanDateTimeTimeSpanDateTime

(著者はここで同じ質問をしましたが、要件は少なかった: SQL 'time' type in Entity Framework Code First )

4

1 に答える 1

2

あなたの問題は、このページの DateTimes の規則を変更するために使用される例と非常によく似ています: Custom Code First Conventions (EF6 以降)

おそらくこのようなもの:

public class TimeSpanConvention : Convention
{
    public TimeSpanConvention()
    {
        this.Properties<TimeSpan>()
            .Configure(c => c.HasColumnType("datetime"));        
    }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add(new TimeSpanConvention());
}

編集質問をもう一度読んでください。C#コードにDateTimeが必要であり、データベースにtime(0)が必要であることがわかります。その逆では機能しません。残念ながら、このソリューションConvert value when mappingのような 2 つのフィールドが必要になると思われます。これにより、データベース プロパティがプライベートに保たれます。

命名規則に基づいているが、カスタムコーディング規則の元のアイデアはどうですか:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<DateTime>()
                .Where(p => p.Name.EndsWith("TimeOfDay"))
                .Configure(p => p.HasColumnType("time(0)"));
}

EDIT 2 そして、それは無効なマッピングであるため、選択肢がほとんどありません。

モデルでは:

private string DBTimeOfDay { get; set; }

[System.ComponentModel.DataAnnotations.Schema.NotMapped]
public DateTime TimeOfDay
{
    get { return new DateTime(DBTimeOfDay.Ticks); }
    set { DBTimeOfDay= value.TimeOfDay; }
}

Context クラスでは次のようになります。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{      modelBuilder.Types().Configure(c =>
   {
      var properties = c.ClrType.GetProperties(BindingFlags.NonPublic 
                                         | BindingFlags.Instance)
                             .Where(p => p.Name == "DBTimeOfDay");
       foreach (var p in properties)
           c.Property(p).HasColumnName("TimeOfDay");
   });
}

別のオプションは、SQL に変換するデータベース ビューを作成し、time(0)更新DateTimeのために変更されたストアド プロシージャにマップすることです。その手法は、サポートされていないデータ型に対して提案されています

編集 3 ! これで寝て…ここに私の考えがあります。

time(0) は時刻を表します。

Entity Framework は、それを に変換することを選択しましたTimespan

Timespans は期間を表すと想定されています。

Timespanssに簡単に追加されDateTime、結果は新しいものになりますDateTime

TimeOfDayC# にはデータ型がありません

TimeSpanしたがって、ビジネス ロジックでは、24 時間を超えない として、またはDateTime日付部分を無視する任意の値に設定したとして、時刻を保持する必要があります。

EF はDateTime.TimeOfDayTimespan を返すC# と一致しています。

ビジネス ロジックで何らかの計算を行っている場合、たとえば定期的な予定などについては、実際には TimeSpan の方がわずかに強い議論になる可能性があると思います。複雑な場合は、野田時間の使用を開始する必要があります。

問題は、UI に移動するときに発生します。TimeEdit...DateTime午前/午後として表示したい..

そこで、UI で DateTime にマップします。私はMVCを使用しています。ViewModel を使用しています。私はすでにエンティティからマッピングしています。AutoMapperを使用しています。簡単で、エンティティをクリーンに保ちます。UI 用にTimeSpan変換されたドメイン内のプロパティ。DateTime

于 2013-11-13T15:17:32.867 に答える