1

我正在按照指南映射一个对象化的关系(many->many 映射表包含属性)。

生成的 SQL(见异常)正在工作并返回我想要的(严格来说它应该是一个内部连接?)。但我得到一个GenericADOException说法:

无法初始化集合:[Questionnaires.Core.Questionnaire.Questions#CBDEDAFC183B4CD7AF1422423A91F589] [SQL:SELECT questions0_.ida_questionnaire_id为ida4_2_,questions0_.ida_questionnaire_question_id为ida1_2_,questions0_.ida_questionnaire_question_id为ida1_5_1_,questions0_.question_no为question2_5_1_,questions0_.ida_question_id为ida3_5_1_ ,questions0_.ida_questionnaire_id如ida4_5_1_,question1_.ida_question_id如ida1_3_0_,question1_.ida_question_type_id如ida2_3_0_,question1_.description如descript3_3_0_,question1_.validate_max如validate4_3_0_,question1_.validate_min如validate5_3_0_ FROM ida_questionnaire_question questions0_左外连接ida_question question1_上questions0_.ida_question_id = question1_ .ida_question_id WHERE questions0_.ida_questionnaire_id=?]

我猜这是因为Questionnaire它真的映射到QuestionnaireQuestionQuestionQuestionnaire-> hasMany-> QuestionnaireQuestion<- hasMany<- Question)。但我似乎无法找到解决这个问题的方法。

问题:

public class Question : PersistentObjectWithTypedId<string>
{
    #region Constructors

    public Question()
    {
        Alternatives = new List<Alternative>();
        Questionnaires = new List<Questionnaire>();
    }
    public Question(string description)
        : this()
    {
        Check.Require(!string.IsNullOrEmpty(description) && description.Trim() != string.Empty);
        Description = description;
    }

    #endregion

    #region Properties

    public virtual string Type { get; set; }
    public virtual string Description { get; set; }
    public virtual int Order { get; set; }
    public virtual IList<Questionnaire> Questionnaires { get; set; }
    public virtual IList<Alternative> Alternatives { get; set; }
    public virtual Validator MyValidator { get; set; }
}

public class QuestionMap : ClassMap<Question>
{
    public QuestionMap()
    {
        WithTable("ida_question");
        Id(x => x.ID, "ida_question_id").WithUnsavedValue(0).GeneratedBy.UuidHex("");
        Map(x => x.Description, "description").AsReadOnly();
        Map(x => x.Type, "ida_question_type_id").AsReadOnly();

        Component<Core.Validator>(x => x.MyValidator, m =>
            {
                m.Map(x => x.Type, "ida_question_type_id");
                m.Map(x => x.RangeMin, "validate_min");
                m.Map(x => x.RangeMax, "validate_max");
            });

        HasMany<QuestionnaireQuestion>(x => x.Questionnaires)
            .Cascade.AllDeleteOrphan()
            .WithKeyColumn("ida_question_id");

        HasMany<Alternative>(x => x.Alternatives)
            .IsInverse()
            .WithKeyColumn("ida_question_id")
            .AsBag().SetAttribute("cascade", "all");
    }
}

问卷问题:

public class QuestionnaireQuestion : PersistentObjectWithTypedId<string>
{
    protected QuestionnaireQuestion()
    {
    }

    public virtual int QuestionOrder { get; set; }
    public virtual Question Question {get;set;}
    public virtual Questionnaire Questionnaire { get; set; }
}

public class QuestionnaireQuestionMap : ClassMap<QuestionnaireQuestion>
{
    public QuestionnaireQuestionMap()
    {
        WithTable("ida_questionnaire_question");
        SetAttribute("lazy", "false");
        Id(x => x.ID, "ida_questionnaire_question_id")
            .WithUnsavedValue(0)
            .GeneratedBy.UuidHex("");

        References(x => x.Question, "ida_question_id")
            .WithForeignKey("ida_question_id")
            .FetchType.Join();

        References(x => x.Questionnaire, "ida_questionnaire_id")
            .WithForeignKey("ida_questionnaire_id")
            .FetchType.Join();

        Map(x => x.QuestionOrder, "question_no");
    }
}

问卷:

public class Questionnaire : PersistentObjectWithTypedId<string>
{
    #region Constructors

    public Questionnaire()
    {
        Questions = new List<Question>();
    }
    public Questionnaire(string description) : this()
    {
        Check.Require(!string.IsNullOrEmpty(description) && description.Trim() != string.Empty);
        Description = description;
    }

    #endregion

    #region Properties

    public virtual string Description { get; set; }
    public virtual IList<Question> Questions { get; set; }

    #endregion
}

public class QuestionnaireMap : ClassMap<Questionnaire>
{
    public QuestionnaireMap(){
        WithTable("ida_questionnaire");
        SetAttribute("lazy", "false");
        Id(x => x.ID, "ida_questionnaire_id")
            .WithUnsavedValue(0)
            .GeneratedBy.UuidHex("");

        Map(x => x.Description);

        HasMany<QuestionnaireQuestion>(x => x.Questions)
            .Cascade.AllDeleteOrphan()
            .WithKeyColumn("ida_questionnaire_id");
    }
}

在数据库中的异常中运行 SQL 的结果是 6 行(预期数量),其中包含:

  • IDA4_2_:指南
  • IDA1_2_:指南
  • IDA1_5_1_:指南
  • QUESTION2_5_1:编号(订单属性)
  • IDA3_5_1_:指南
  • IDA4_5_1:指南
  • IDA1_3_0_:指南
  • IDA2_3_0_:手机(类型属性)
  • DESCRIPT3_3_0_:mobiletelefon(描述属性)
  • VALIDATE4_3_0_:(RangeMin 属性)
  • VALIDATE5_3_0_:(RangeMax 属性)

完整的例外是:

[InvalidCastException:不能使用对象类型 Questionnaires.Core.QuestionnaireQuestion 作为 Questionnaires.Core.Question。] NHibernate.Collection.Generic.PersistentGenericBag`1.ReadFrom(IDataReader 阅读器,ICollectionPersister 持久化器,ICollectionAliases 描述符,对象所有者)+160 NHibernate.Loader。 Loader.ReadCollectionElement(对象 optionalOwner,对象 optionalKey,ICollectionPersister 持久化器,ICollectionAliases 描述符,IDataReader rs,ISessionImplementor 会话)+407 NHibernate.Loader.Loader.ReadCollectionElements(Object[] 行,IDataReader 结果集,ISessionImplementor 会话)+412 NHibernate.Loader.Loader .GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydradObjects, EntityKey[] 键,Boolean returnProxies) +472 NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +1010 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +114 NHibernate.Loader.Loader.LoadCollection (ISessionImplementor 会话,对象 id,IType 类型)+362

[GenericADOException:无法初始化集合:[Questionnaires.Core.Questionnaire.Questions#CBDEDAFC183B4CD7AF1422423A91F589] [SQL:SELECT questions0_.ida_questionnaire_id为ida4_2_,questions0_.ida_questionnaire_question_id为ida1_2_,questions0_.ida_questionnaire_question_id为ida1_5_1_,questions0_.question_no为question2_5_1_,questions0_。 ida_question_id为ida3_5_1_,questions0_.ida_questionnaire_id为ida4_5_1_,question1_.ida_question_id为ida1_3_0_,question1_.ida_question_type_id为ida2_3_0_,question1_.description为descript3_3_0_,question1_.validate_max为validate4_3_0_,question1_.validate_min作为validate5_3_0_ FROM ida_questionnaire_question questions0_留在questions0_外连接ida_question question1_。 ida_question_id=question1_.ida_question_id WHERE questions0_.ida_questionnaire_id=?]] NHibernate.Loader。Loader.LoadCollection(ISessionImplementor session, Object id, IType type) +528 NHibernate.Loader.Collection.CollectionLoader.Initialize(Object id, ISessionImplementor session) +74 NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize(Object key, ISessionImplementor session) + 59 NHibernate.Event.Default.DefaultInitializeCollectionEventListener.OnInitializeCollection(InitializeCollectionEvent 事件) +573 NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection 集合,布尔写法) +150 NHibernate.Collection.AbstractPersistentCollection.ForceInitialization() +287 NHibernate.Engine.StateonfulsLatestCollection () +213 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters,Boolean returnProxies) +171 NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) +493 NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId) +82 NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session) +54 NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor 会话)+206 NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent 事件,IEntityPersister 持久化,EntityKey keyToLoad,LoadType 选项)+133 NHibernate.Event.Default。DefaultLoadEventListener.DoLoad(LoadEvent 事件,IEntityPersister 持久化,EntityKey keyToLoad,LoadType 选项)+948 NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent 事件,IEntityPersister 持久化,EntityKey keyToLoad,LoadType 选项)+436 NHibernate.Event.Default.DefaultLoadEventListener。 ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) +236 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType) +1303 NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType) +125 NHibernate.Impl.SessionImpl.Get(String entityName, Object id) +145 NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id) +66 NHibernate.Impl.SessionImpl.Get(Object id) +91 SharpArch.Data.NHibernate .RepositoryWithTypedId`2.Get(IdT id) +152 Questionnaires.Controllers.QuestionnaireController.Create(String username, String id) in C:\Documents and Settings\berbor\Mine dokumenter\Visual Studio 2008\Projects\Questionnaires\Questionnaires.Controllers\ QuestionnaireController.cs:40 lambda_method(ExecutionScope, ControllerBase, Object[]) +205 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase 控制器, Object[] 参数) +17 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 个参数)+178 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext,ActionDescriptor actionDescriptor,IDictionary`2 个参数)+24 System.Web.Mvc.<>c__DisplayClassa.b__7() +52 System.Web.Mvc .ControllerActionInvoker。InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +254 System.Web.Mvc.<>c__DisplayClassc.b__9() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 过滤器, ActionDescriptor actionDescriptor , IDictionary`2 参数) +192 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +350 System.Web.Mvc.Controller.ExecuteCore() +110 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)+27 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)+7 System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)+119 System.Web.Mvc.MvcHandler。ProcessRequest(HttpContext httpContext) +41 System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181 System.Web .HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75


至于我这样做的原因:

一个问卷可能有很多问题,一个问题可能有很多问卷。我希望能够Questions根据上下文(Questionnaire在其中)给出一些属性,一个问题可能需要在一个调查问卷中,而不是另一个问题等。这不仅仅是顺序,这只是一个试图保持简单的例子。

尝试将数据加载到Questionnaire.IList<Question>. 在我修改我IList<Questionnaire>的 toIList<QuestionnaireQuestion>和相应的映射后,它仍然被抛出。

那么问题将Questionnaire.Questions是映射为包含QuestionnaireQuestion但类型为Question。但是,如果我尝试将其映射为包含QuestionnaireQuestion我的 SQL,则根本不加入,它仍然会失败。这是我应该做的,只是我做错了吗?在我读到的示例中,他就像我所看到的那样做,唯一的区别是现在使用泛型的 FluentNhibernate 的较新版本。所以我需要指定正确的类型。

4

2 回答 2

3

然后,您的 Question 类中不应该有一个 List of Questionnaires,而是一个 List of QuestionnaireQuestion 对象。

于 2009-02-05T10:44:48.560 回答
1

您确定收到 ADO.NET Exception 吗?你可以对你的数据库执行生成的查询吗?

但是我不明白你的情况,这个 QuestionairreQuestion 类是什么?您没有在 Question 课程中使用它吗?我了解您希望有一个您的问题应该出现的顺序。
所以,如果你有额外的属性,我认为你应该在 Question 类中使用 QuestionairreQuestion 类。但是,如果您只有这个 QuestionairreQuestion 类来强制执行“订单”(并且没有其他属性),那么您可以使用另一个 Collection-Type 而不是 IList。
NHibernate 中有一些集合允许您拥有有序集合(例如 map )。因此,您可以在 Question 类中使用此集合来保存 Questionairre 对象。

(ps:nhibernate 生成一个外连接,因为您没有在映射中指定集合不应为空。因此,使用外连接是因为在某些情况下,您可能有一个没有 Questionaires 的 Question,就 nhibernate 而言)。

于 2009-02-05T10:12:35.677 回答