このガイドに従って、オブジェクト化された関係 (many->many マッピング テーブルにはプロパティが含まれています) をマッピングしています。
生成された SQL (例外を参照) は機能しており、必要なものを返します (厳密に言えば、内部結合であるべきでしたか?)。しかし、私はGenericADOException
言います:
could not initialize a collection: [Questionnaires.Core.Questionnaire.Questions#CBDEDAFC183B4CD7AF1422423A91F589][SQL: SELECT questions0_.ida_questionnaire_id as ida4_2_, questions0_.ida_questionnaire_question_id as ida1_2_, questions0_.ida_questionnaire_question_id as ida1_5_1_, questions0_.question_no as question2_5_1_, questions0_.ida_question_id as ida3_5_1_ , questions0_.ida_questionnaire_id as ida4_5_1_, question1_.ida_question_id as ida1_3_0_, question1_.ida_question_type_id as ida2_3_0_, question1_.description as descript3_3_0_, question1_.validate_max as validate4_3_0_, question1_.validate_min as validate5_3_0_ FROM ida_questionnaire_question questions0_ left outer join ida_question question1_ on questions0_.ida_question_id=question1_ .ida_question_id WHERE question0_.ida_questionnaire_id=?]
これは、実際には not ( -> -> <- <- )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");
}
}
DB の例外で SQL を実行した結果は、以下を含む 6 行 (期待される数) です。
- IDA4_2_: ガイド
- IDA1_2_: ガイド
- IDA1_5_1_: ガイド
- QUESTION2_5_1: Number (注文プロパティ)
- IDA3_5_1_: ガイド
- IDA4_5_1: ガイド
- IDA1_3_0_: ガイド
- IDA2_3_0_: MOBILEPHONE (型プロパティ)
- DESCRIPT3_3_0_: mobiltelefon (説明プロパティ)
- 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(Object optionalOwner、Object optionalKey、ICollectionPersister 永続化、ICollectionAliases 記述子、IDataReader rs、ISessionImplementor セッション) +407 NHibernate.Loader.Loader.ReadCollectionElements(Object[] 行、IDataReader resultSet、ISessionImplementor セッション) +412 NHibernate.Loader.Loader .GetRowFromResultSet(IDataReader 結果セット、ISessionImplementor セッション、QueryParameters queryParameters、LockMode[] lockModeArray、EntityKey optionalObjectKey、IList hydratedObjects、EntityKey[] キー、Boolean returnProxies) +472 NHibernate.Loader.Loader.DoQuery(ISessionImplementor セッション、QueryParameters queryParameters、Boolean returnProxies) +1010 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor セッション、QueryParameters queryParameters、Boolean returnProxies) +114 NHibernate.Loader.Loader.LoadCollection (ISessionImplementor セッション、オブジェクト ID、IType タイプ) +362
[GenericADOException: could not initialize a collection: [Questionnaires.Core.Questionnaire.Questions#CBDEDAFC183B4CD7AF1422423A91F589][SQL: SELECT questions0_.ida_questionnaire_id as ida4_2_, questions0_.ida_questionnaire_question_id as ida1_2_, questions0_.ida_questionnaire_question_id as ida1_5_1_, questions0_.question_no as question2_5_1_, questions0_. ida_question_id as ida3_5_1_, questions0_.ida_questionnaire_id as ida4_5_1_, question1_.ida_question_id as ida1_3_0_, question1_.ida_question_type_id as ida2_3_0_, question1_.description as descript3_3_0_, question1_.validate_max as validate4_3_0_, question1_.validate_min as validate5_3_0_ FROM ida_questionnaire_question questions0_ left outer join ida_question question1_ on questions0_. ida_question_id=question1_.ida_question_id WHERE question0_.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.zyLayonLayer () +213 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor セッション、QueryParameters queryParameters、Boolean returnProxies) +171 NHibernate.Loader.Loader.LoadEntity(ISessionImplementor セッション、オブジェクト ID、IType identifierType、オブジェクト optionalObject、文字列 optionalEntityName、オブジェクト optionalIdentifier、IEntityPersister 永続化) +493 NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor セッション、オブジェクトid、オブジェクト optionalObject、オブジェクト optionalId) +82 NHibernate.Loader.Entity.AbstractEntityLoader.Load(オブジェクト id、オブジェクト optionalObject、ISessionImplementor セッション) +54 NHibernate.Persister.Entity.AbstractEntityPersister.Load(オブジェクト id、オブジェクト 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 イベント、IEntityPersister 永続化、EntityKey keyToLoad、LoadType オプション) +236 NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent イベント、LoadType loadType) +1303 NHibernate.Impl.SessionImpl.FireLoad(LoadEvent イベント、LoadType loadType) +125 NHibernate.Impl.SessionImpl.Get(文字列エンティティ名、オブジェクト ID) +145 NHibernate.Impl.SessionImpl.Get(タイプ entityClass、オブジェクト ID) +66 NHibernate.Impl.SessionImpl.Get(オブジェクト 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 controller, Object[] parameters) +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 フィルター、ActionExecutingContext preContext、Func`1 継続) +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 ステップ、ブール値 & 完了した同期) +75
私がこれをしている理由については:
1 つのアンケートに複数の質問が含まれる場合もあれば、1 つの質問に複数のアンケートが含まれる場合もあります。Questions
コンテキスト (含まれている) に応じていくつかのプロパティを指定できるようにしたいと考えていますQuestionnaire
。あるアンケートでは 1 つの質問が必要になる場合がありますが、別の質問では必要ない場合があります。
例外は、データを にロードしようとする場合Questionnaire.IList<Question>
です。IList<Questionnaire>
そして、 toIList<QuestionnaireQuestion>
とそれぞれのマッピングを変更した後もスローされます。
問題は、それがQuestionnaire.Questions
含むとしてマップされているQuestionnaireQuestion
が、タイプであるということQuestion
です。しかし、SQL を含むものとしてマップしようとすると、QuestionnaireQuestion
まったく結合されず、それでも失敗します。やり方が間違っているだけで、これは私がすべきことですか?私が読んだ例では、私が見る限り、彼は私と同じようにそれを行っています.唯一の違いは、現在ジェネリックを使用しているFluentNhibernateの新しいバージョンです. したがって、正しいタイプを指定する必要があります。