0

階層ごとのテーブル (TPH) を使用して、変数と派生クラスというエンティティを定義しました。基本クラス「Variable」には、PropertyValues のコレクションが含まれています。

private ICollection<PropertyValue> propertyValues;

public const string DiscriminatorColumn = "Discriminator";
public const string Table = "Variables";

public VariableType VariableType { get; set; }
public string Name { get; set; }

[NotMapped]
public string Discriminator { get; set; }

public virtual ICollection<PropertyValue> PropertyValues
{
    get { return this.propertyValues ?? (this.propertyValues = new ObservableCollection<PropertyValue>()); }
    set { SetProperty(ref this.propertyValues, value, () => PropertyValues); }
}

ここで、PropertyValues (テーブル) のエントリにマップする必要がある SpecialProperties (HighLimit など) を定義する SpecialVariable クラス (または複数) を派生させたいと考えています。

public class MySpecialVariabe : Variable
{
    public double HighLimit { get; set; }
}

私の OnModelCreating 関数は現在次のようになっています。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Variable>().HasKey(x => new { x.Id });

    modelBuilder.Entity<Variable>()
        .Map<MySpecialVariabe>(m => m.Requires(Variable.DiscriminatorColumn).HasValue(typeof(MySpecialVariabe).Name))
        .Map<MySpecialVariabe2>(m => m.Requires(Variable.DiscriminatorColumn).HasValue(typeof(MySpecialVariabe2).Name)).ToTable(Variable.Table);
}

派生クラスに見栄えの悪いコードを大量に書かずに、これを実現する方法のヒントを教えてください。(パフォーマンスはそれほど重要ではありません。)

よろしくお願いします、

クリス

4

1 に答える 1

1

プロパティをレコードにマップすることはできません。それが私があなたの質問を理解する方法です。おそらくキーと値のペアである PropertyValues テーブルがいくつかあり、エンティティ プロパティをレコード (データ) としてこのテーブルにマップしたいとします。これは、EF が行うことではありません。propertyValues コレクションの正しいレコードで機能するマップされていないプロパティを提供する必要があります。

何かのようなもの:

[NotMapped]
public double HighLimit
{
  get
  {
    var current = propertyValues.SingleOrDefault(p => p.Key == "HighLimit");
    return current != null ? current.Value : 0.0;
  }
  set 
  {
    var current = propertyValues.SingleOrDefault(p => p.Key == "HighLimit");
    if (current != null)
    {
      current.Value = value;
    }
    else
    {
      propertyValues.Add(new PropertyValue { Key = "HighLimit", Value = value });
    }
  }
}

このアプローチの問題は、Linq からエンティティへのクエリで HighLimit を使用できないことです。常に PropertyValues を使用する必要があります。

さらに、EF の TPH では、派生エンティティ (MySpecialVariable) のプロパティが親エンティティ (Variable) と同じテーブルにマップされている必要があります。派生エンティティのプロパティを他のテーブル (PropertyValues) に格納されているデータにマップすることはできません。

于 2011-02-16T14:53:29.860 に答える