2009-02-05 71 views
1

我正在映射物化关系(many-> many映射表包含属性), 下面的this指南。与nhibernate映射物化关系无法初始化集合

生成的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_ left outer join ida_question question1_ on questions0_.ida_ques ?tion_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"); 
    } 
} 

QuestionnaireQuestion:

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"); 
    } 
} 

在DB异常运行SQL的结果是6行(预期的数量)conta进不去:

  • IDA4_2_:的GUID
  • IDA1_2_:的GUID
  • IDA1_5_1_:的GUID
  • QUESTION2_5_1:号码(顺序 属性)
  • IDA3_5_1_:的GUID
  • IDA4_5_1:的GUID
  • IDA1_3_0_ :Guids
  • IDA2_3_0_:手机(类型 属性)
  • DESCRIPT3_3_0_:Mobiltelefon公司 (描述属性)
  • VALIDATE4_3_0_:(RangeMin属性)
  • VALIDATE5_3_0_:(的RangeMax属性)

完整的例外是:

[ InvalidCastException:不能使用对象类型Questionnaires.Core.QuestionnaireQuestion作为Questionnaires.Core.Question。] NHibernate.Collection.Generic.Persiste ntGenericBag`1.ReadFrom(IDataReader reader,ICollectionPersister persister,ICollectionAliases descriptor,Object owner)+160 NHibernate.Loader.Loader.ReadCollectionElement(Object optionalOwner,Object optionalKey,ICollectionPersister persister,ICollectionAliases描述符,IDataReader rs,ISessionImplementor会话)+407 NHibernate.Loader.Loader.ReadCollectionElements(对象[]行,IDataReader的结果集和ISessionImplementor会话)412 NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader的结果集和ISessionImplementor会话,QueryParameters queryParameters,LockMode [] lockModeArray,的EntityKey optionalObjectKey,IList的hydratedObjects, EntityKey []键,布尔returnProxies)+472 NHibernate.Loader.Loader.DoQuery(ISessionImplementor会话,QueryParameters queryParameters,布尔returnProxies)+1010 NHibernate。 Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor会议,QueryParameters queryParameters,布尔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_左外连接ida_question question1_上questions0_.ida_question_id = question1_.ida_question_id WHERE questions0_.ida_questionnaire_id =?]] NHibernate.Loader.Loader.LoadCollection(ISessionImplementor会话,对象ID,ITYPE型)528 NHibernate.Loader.Collection.CollectionLoader.Initialize(对象ID,ISessionImplementor会话)+74 NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize(对象键,ISessionImplementor会话)+59 NHibernate.Event.Default.DefaultInitializeCollectionEventListener。 OnInitializeCollection(InitializeCollectionEvent事件)+573 NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection集合,布尔写入)+150 NHibernate.Collection.AbstractPersistentCollection.ForceInitialization()287个 NHibernate.Engine.StatefulPersistenceContext.InitializeNonLazyCollections()213个 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor会话,QueryParameters queryParameters,布尔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)+ NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id,Object optionalObject,ISessionImplementor session)+54 NHibernate.Persister.En tty.AbstractEntityPersister.Load(Object id,Object optionalObject,LockMode lockMode,ISessionImplementor session)+206 NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event,IEntityPersister persister,EntityKey keyToLoad,LoadType选项)+133 NHibernate.Event。 NHibernate.Event.LoadEventListener.DoLoad(LoadEvent事件,IEntityPersister persister,EntityKey keyToLoad,LoadType选项)+948 NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event,IEntityPersister persister,EntityKey keyToLoad,LoadType选项)+436 NHibernate.Event。 Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event,IEntityPersister persister,EntityKey keyToLoad,LoadType选项)+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。执行(ControllerBase控制器,Object []参数)+17 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary`2 parameters)+178 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext,ActionDescriptor actionDescriptor,IDictionary`2 parameters) MVC。 System_Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter过滤器,ActionExecutingContext preContext,Func`1继续)+254 System.Web.Mvc。 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext,IList`1 filters,ActionDescriptor actionDescriptor,IDictionary`2 parameters)+192 System.Web.Mvc.ControllerActionInvoker。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步骤,布尔型& completedSync hronously)+75


至于原因,我这样做:

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

当试图将数据加载到Questionnaire.IList<Question>时是个例外。在修改我的IList<Questionnaire>IList<QuestionnaireQuestion>及其各自的映射之后,它仍然被抛出。

然后问题是Questionnaire.Questions被映射为包含QuestionnaireQuestion但类型为Question。但是,如果我尝试将其映射为包含QuestionnaireQuestion,那么我的SQL根本没有联接,并且仍然失败。 这是我应该做的,只是我做错了吗? 在我读的例子中,他尽我所能地做了它,只是不同的是现在使用泛型的FluentNhibernate的新版本。所以我需要指定正确的类型。

回答

3

然后,您不应该在您的问题类中有调查问卷列表,而是问卷调查对象列表。

+0

谢谢。 这工作时,我也改变了我的调查问卷。Questionnaires.QuestionnaireQuestion的问题。 – Bernt 2009-02-05 12:18:02

1

您确定收到ADO.NET异常吗? 你能对数据库执行生成的查询吗?

但是我不明白你的情况,这是什么QuestionairreQuestion类?你没有在课堂上使用它? 我知道你想要发布问题的顺序。
所以,如果你有额外的属性,我认为你应该在Question类中使用QuestionairreQuestion类。 但是,如果您只有这个QuestionairreQuestion类才能执行'order'(并且没有其他属性),那么您可以使用另一个Collection-Type而不是IList。
有在NHibernate的集合,让你有订购集合(例如地图)。所以,你可以在你的Question类中使用这个集合来保存Questionairre对象。

(ps:nhibernate会生成一个外连接,因为您没有在映射中指定该集合不应该为null,所以使用了外连接,因为在某些情况下,可能有一个外连接问题没有问卷,就nhibernate而言)。