我有以下内容:
public abstract class FooBase
{
public virtual int Id { get; set; }
}
public class Foo1 : FooBase { /* could be stuff here */ }
public class Foo2 : FooBase { /* could be stuff here */ }
public class Bar
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual SOMETHING WhichFoo { get; set }
}
...其中WhichFoo
处理FooBase
使用string
"Foo1"
public class FooBaseMap : ClassMap<FooBase>
{
public FooBaseMap()
{
this.Id(x => x.Id);
this.DiscriminateSubClassesOnColumn("Type");
}
}
public class Foo1Map : SubclassMap<Foo1>
{
public Foo1Map() { this.DiscriminatorValue("Foo1"); }
}
public class Foo2Map : SubclassMap<Foo2>
{
public Foo2Map() { this.DiscriminatorValue("Foo2"); }
}
但这看起来非常混乱。
使用映射:
Foo
我希望能够根据Bar
中存储的值创建新的Bar bar = this.Session.Get<Bar>(1);
FooBase foo1 = bar.GetANewFoo(); // returns a new Foo1
Bar anotherBar = this.Session.Get<Bar>(123);
FooBase foo2 = bar.GetANewFoo(); // returns a new Foo2
,1或2。所以:
GetANewFoo()
Foo1
可以是一个方法,一个返回Foo2
或FooBase
的空实例的属性。
实际上我想要做的是在GetANewFoo
中存储Bar
要创建的"Foo1"
类型。
当我创建一个时,没有明确地手动将"Foo2"
或Bar
写入{{1}},最好的方法是什么?
答案 0 :(得分:0)
您可以在Bar表中创建一个列,它将保存它的Foo类型。因此,如果此SOMETHING
类型的属性为enum
,string
或int
(无论如何),您可以使用switch-case statement
来识别Foo,创造你需要的东西并回归。
就像这样:
public FooBase GetANewFoo()
{
switch (WhichFoo)
{
case "Foo1": return new Foo1();
case "Foo2": return new Foo2();
default: return null;
}
}
答案 1 :(得分:0)
好吧,我想我明白了 - 实际上是rehashing a method I used for the Strategy Pattern。
public abstract class FooFactoryBase
{
protected FooFactoryBase() { } // for NHibernate
protected FooFactoryBase(Guid id)
{
this.Id = id;
}
public virtual Guid Id { get; set; }
public virtual IList<Bar> Bars { get; set; }
public abstract FooBase CreateFoo();
}
public class Foo1Factory : FooFactoryBase
{
public readonly static Guid Guid = new Guid("abc123...");
public Foo1Factory() : base(Guid) { }
public override FooBase CreateFoo()
{
return new Foo1();
}
}
然后Bar
成为:
public class Bar
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual FooFactoryBase FooFactory { get; set; }
}
并映射:
public class BarMap : ClassMap<Bar>
{
this.Id(x => x.Id);
this.Map(x => x.Name);
this.References(x => x.FooFactory);
}
public class FooFactoryBaseMap : ClassMap<FooFactoryBase>
{
this.Id(x => x.Id);
this.HasMany(x => x.Bars).Inverse();
this.DiscriminateSubClassesOnColumn("Id");
}
public class Foo1FactoryMap : SubClassMap<Foo1Factory>
{
this.DiscriminatorValue(Foo1Factory.Guid);
}
现在,当我创建数据库时,我可以使用FooFactory
来填充它,添加Bars
时我可以从数据库中加载适当的Factory
,然后调用我的代码这样:
Bar bar = this.Session.Get<Bar>(10);
FooBase foo = bar.FooFactory.CreateFoo();
将创建相应的FooBase
。
有时你只需要问这个问题就可以解决:)