1

カスタムフォームデザイナーを実装しています。これで、レイアウトをデータベースに永続化することができます。

テクノロジーの制限

  • .NET 4.0
  • NHibernate
  • 流暢なNHibernate
  • MSSQL 2008 R2

これが私が思いついたデザインです:

コントロールテーブル

  • Id int Identity
  • varchar(300)と入力します

ControlPropertiesテーブル

  • Id int Identity
  • ControlIdintFKからControls.IDへ
  • 名前varchar(300)
  • 値varchar(max)

コントロールクラス

public class Control
{
  public virtual int Id { get; set; }
  public virtual string Type { get; set; }
  public virtual Dictionary<string, string> Properties { get; set; }
}

次に、これをマップして、レイアウトをリロードするために次のようなことを実行できるようにします。

var controls = GetListOfControlsUsingNHibernate();
foreach (var control in controls){
  var newControl = CreateControlFromType(control.Type);
  SetPropertiesViaTypeDescriptor(newControl, control.Properties);
  this.Controls.Add(newControl);
}

2つの質問があります。

  1. Fluent NHibernateを使用してこれをどのようにマッピングしますか?
  2. EAVを含まず、すべての値を文字列として格納するより良いアプローチはありますか?
4

2 に答える 2

1

それを行うためのいくつかの代替方法。

1つの解決策は、継承を使用することです

public abstract class Control
{
    // ...
}
public class TextBox : Control
{
    public virtual string Text { get; set; }
}
public class MaskedTextBox : TextBox
{
    public virtual string Mask { get; set; }
}

もう1つは、さまざまな種類のプロパティを使用することです

public class Control
{
  public virtual ISet<Property> Properties { get; set; }
} 
public abstract class Property
{
  public virtual string Name { get; set; }
}
public class IntProperty : Property
{
  public virtual int Value { get; set; }
}
public class DecimalProperty : Property
{
  public virtual decimal Value { get; set; }
}
// ...

さらにもう1つは、インターフェイスを使用することです

public abstract class Control
{
}
public class TextBox : Control, ITextControl
{
  public virtual string Text { get; set; }
}


public class ConcreteControlMap<T> : SubclassMap<T> where T : Control
{
  public ConcreteControlMap()
  {
    if(typeof(ITextControl).IsAssignableFrom(typeof(T)))
    {
      Map(c => ((ITextControl)c).Text);
    }
  }
}
于 2013-02-20T06:46:59.970 に答える
0

Twitterのつぼみは、FluentNHibernateを使用してこれをマッピングするための正しい方向を示しました。

まずProperties、プロパティを保持するための名前のテーブルを作成します。

╔═══════════╦══════════════╦═══════════════╗
║ ControlId ║ PropertyName ║ PropertyValue ║
╚═══════════╩══════════════╩═══════════════╝

次に、マッピングを次のように変更します。

public class ControlMap : ClassMap<Control>
{
    public ControlMap()
    {
        Table("Controls");
        Id(x => x.Id);
        Map(x => x.Type);
        HasMany(x => x.Properties).Table("ControlProperties")
            .AsMap<string>(index => index.Column("PropertyName").Type<string>(),
                           element => element.Column("PropertyValue").Type<string>())
            .Cascade.All(); 
    }
}

この背後にあるhbmxmlの背景については、AyendeのNHibernateマッピングマップを参照してください。

于 2013-02-21T20:03:26.290 に答える