我需要对具有复合主键(Azure Table,主键if (PartitionKey,RowKey) )的表使用Fluent-nHibernate,并且我希望使用实体上的相应属性(或者使用组件属性(如果更容易)来映射它们)。
我的桌子看起来像:
{
PartitionKey PK,
RowKey PK,
[..]
}和实体
public class MyRecord
{
public virtual string PartitionKey{get;set;}
public virtual string RowKey{get;set;}
[...]
}我目前的项目使用了一个针对AzureTable的自定义AzureTable驱动程序。
我设法使它与ClassMap或XML映射一起工作。因此,我确信司机在工作。此外,使用类映射或XML声明,蔚蓝表HTTP请求是正确的。
但是我真的需要约定,所以这不是一个可以接受的解决方案。
最后,始终有将RowKey映射为PK的选项,即使数据存储使用(PartitionKey,RowKey)。它也能工作,但是并不令人满意,因为它引入了nHibernate和底层数据存储之间的单一性处理不匹配。
更新:
我试图构建一个定制的IIdentityConvention。IIdentityInstance.Column()方法只考虑第一个调用。但是,如果我使用反射将两列添加到基础映射字段,配置构建将失败,出现XML验证异常(属性'class‘必需)。
发布于 2012-01-21 05:26:19
我今天让它起作用了,但它不漂亮。它也不使用约定。正如我所理解的那样,它们实际上是用来在主映射发生后调整事物的。我认为添加映射被认为超出了约定的范围。
在我的项目中,我有一个基于通用自动化的初始化过程,它不知道类型,但对复合键具有依赖注入映射覆盖。不完全是你的情况,但这是一个类似的问题。
我让它通过反射工作的方式是获得适当的AutoPersistenceModel对象。如果您的代码如下所示:
Fluently.Configure().Mappings(m => ...AutoPersistenceModel对象将是m.AutoMappings.First()
从这里开始,这是非常严肃的反射工作,最终在FluentNHibernate中调用一个受保护的方法。下面是我使用的代码:
private void Override(AutoPersistenceModel container,
Type type,
IEnumerable<KeyValuePair<string,string>> compositeKeys)
{
// We need to call container.Override<T>(Action<Automapping<T>> populateMap)
// Through reflection...yikes
var overrideMethod = typeof(AutoPersistenceModel)
.GetMethod("Override")
.MakeGenericMethod(type);
var actionFactoryMethod = typeof(FluentNHibernateInitializer)
.GetMethod("CompositeMapperFactory",
BindingFlags.Instance | BindingFlags.NonPublic)
.MakeGenericMethod(type);
var actionMethod = actionFactoryMethod
.Invoke(this, new object[] { compositeKeys });
overrideMethod.Invoke(container, new object[] {actionMethod});
}
private Action<AutoMapping<T>> CompositeMapperFactory<T>
(IEnumerable<KeyValuePair<string, string>> compositeKeys)
{
return new Action<AutoMapping<T>>(m =>
{
var compositeId = m.CompositeId();
foreach (var kvp in compositeKeys)
compositeId =
AddKeyProperty(
compositeId,
typeof(T).GetProperty(kvp.Key),
kvp.Value);
}
);
}
/// <summary>
/// Uses reflection to invoke private and protected members!
/// </summary>
/// <param name="compositeId"></param>
/// <param name="propertyInfo"></param>
/// <returns></returns>
private CompositeIdentityPart<T> AddKeyProperty<T>
(CompositeIdentityPart<T> compositeId,
PropertyInfo propertyInfo,
string column)
{
var member = FluentNHibernate.MemberExtensions.ToMember(propertyInfo);
var keyPropertyMethod = typeof(CompositeIdentityPart<T>)
.GetMethod("KeyProperty",
BindingFlags.Instance | BindingFlags.NonPublic);
return (CompositeIdentityPart<T>)
keyPropertyMethod
.Invoke(compositeId, new object[] { member, column, null });
}https://stackoverflow.com/questions/6955515
复制相似问题