首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fluent-nHibernate通过公约复合主键声明

fluent-nHibernate通过公约复合主键声明
EN

Stack Overflow用户
提问于 2011-08-05 11:27:15
回答 1查看 749关注 0票数 0

我需要对具有复合主键(Azure Table,主键if (PartitionKey,RowKey) )的表使用Fluent-nHibernate,并且我希望使用实体上的相应属性(或者使用组件属性(如果更容易)来映射它们)。

我的桌子看起来像:

代码语言:javascript
复制
{
  PartitionKey PK,
  RowKey PK,
  [..]
}

和实体

代码语言:javascript
复制
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‘必需)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-21 05:26:19

我今天让它起作用了,但它不漂亮。它也不使用约定。正如我所理解的那样,它们实际上是用来在主映射发生后调整事物的。我认为添加映射被认为超出了约定的范围。

在我的项目中,我有一个基于通用自动化的初始化过程,它不知道类型,但对复合键具有依赖注入映射覆盖。不完全是你的情况,但这是一个类似的问题。

我让它通过反射工作的方式是获得适当的AutoPersistenceModel对象。如果您的代码如下所示:

代码语言:javascript
复制
Fluently.Configure().Mappings(m => ...

AutoPersistenceModel对象将是m.AutoMappings.First()

从这里开始,这是非常严肃的反射工作,最终在FluentNHibernate中调用一个受保护的方法。下面是我使用的代码:

代码语言:javascript
复制
    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 });
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6955515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档