有谁知道我们如何使用NHibernate中的Fluent Automapping自动映射动态组件?
我知道我们可以将普通类映射为组件,但无法弄清楚如何使用流畅的自动化将字典映射为动态组件。
由于
答案 0 :(得分:5)
我们已成功使用以下方法(使用 FluentNH 1.2.0.712 ):
public class SomeClass
{
public int Id { get; set; }
public IDictionary Properties { get; set; }
}
public class SomeClassMapping : ClassMap<SomeClass>
{
public SomeClassMapping()
{
Id(x => x.Id);
// Maps the MyEnum members to separate int columns.
DynamicComponent(x => x.Properties,
c =>
{
foreach (var name in Enum.GetNames(typeof(MyEnum)))
c.Map<int>(name);
});
}
}
这里我们将一些Enum的所有成员映射到单独的列,其中所有成员都是 int 类型。现在我正在开发一个场景,我们为动态列使用不同的类型,而不是:
// ExtendedProperties contains custom objects with Name and Type members
foreach (var property in ExtendedProperties)
{
var prop = property;
part.Map(prop.Name).CustomType(prop.Type);
}
这也很有效。
我还要弄清楚如何使用References
代替Map
来引用具有自己的映射的其他类型...
<强>更新强> 不幸的是,参考文献的案例更复杂,请参阅this Google Groups thread。简而言之:
// This won't work
foreach (var property in ExtendedProperties)
{
var prop = property;
part.Reference(dict => dict[part.Name]);
}
// This works but is not very dynamic
foreach (var property in ExtendedProperties)
{
var prop = property;
part.Reference<PropertyType>(dict => dict["MyProperty"]);
}
这就是现在。
答案 1 :(得分:0)
我遇到了完全相同的问题。使用流畅的 nHibernate 我们无法映射它,但我自己以某种方式能够解决这个问题。我的解决方案是动态构建 lambda 表达式并将其分配给对象。例如,让我们说:
让我复制奥利弗引用的网站部分:
DynamicComponent(
x => x.Properties,
part =>
{
// Works
part.Map("Size").CustomType(typeof(string));
// Works
var keySize = "Size";
part.Map(keySize).CustomType(typeof(string));
// Does not work
part.Map(d => d[keySize]).CustomType(typeof(string));
// Works
part.References<Picture>(d => d["Picture"]);
// Does not work
var key = "Picture";
part.References<Picture>(d => d[key]);
});
我们有这个问题,我们需要在映射中对“图片”进行硬编码。但不知何故,经过一些研究,我创建了以下解决方案:
var someExternalColumnNames = GetFromSomewhereDynamicColumns();
'x' is a DynamicComponent callback in fluent Nhibernate e.g. (DynamicColumns): DynamicComponent(a => a.DynamicColumns, x => (...content of method below...))
foreach(var x in someExternalColumnNames)
{
if (x.IsReferenceToPerson == true)
{
var param = Expression.Parameter(typeof(IDictionary), "paramFirst");
var key = Expression.Constant(x.Name);
var me = MemberExpression.Call(param, typeof(IDictionary).GetMethod("get_Item"), new[] { key });
var r = Expression.Lambda<Func<IDictionary, object>>(me, param);
m.References<Person>(r, x.Name);
}
else
{
m.Map(x.Name)
}
}
//
// Some class that we want to reference, just an example of Fluent Nhibernate mapping
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Table("Person");
Id(x => x.PersonId, "PersonId");
Map(x => x.Name);
}
}
public class Person
{
public virtual Guid PersonId { get; set; }
public virtual string Name { get; set; }
public Person()
{ }
}
也许会有帮助