我正在按照本指南映射一个对象化的关系(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
它真的映射到QuestionnaireQuestion
不Question
(Questionnaire
-> 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 的较新版本。所以我需要指定正确的类型。