I have a DAL using Fluent NHibernate for mapping a query (stored in db as strings) and their parameters (stored in a separate table).
When I try to use this list of parameters in the service layer, I run into problems.
List<QueryParameter> lqp = (List<QueryParameter>)qry.parameters;
Throws
Unable to cast object of type Hibernate.Collection.Generic.PersistentGenericBag
1[nha.cs.utility.mole.QueryParameter]' to type 'System.Collections.Generic.List
1 [nha.cs.utility.mole.QueryParameter]'.
List<QueryParameter> lqp = qry.parameters.ToList<QueryParameter>();
Throws
Initializing[nha.cs.utility.mole.Query#24]-failed to lazily initialize a collection of role: nha.cs.utility.mole.Query.parameters, no session or session was closed
List<QueryParameter> lqp = new List<QueryParameter>(qry.parameters);
Throws
Test method MoleSVSTest.MoleSVCTester.MoleSVCTestMethod threw exception: NHibernate.LazyInitializationException:
Initializing[nha.cs.utility.mole.Query#24]-failed to lazily initialize a collection of role: nha.cs.utility.mole.Query.parameters, no session or session was closed
IList<QueryParameter> lqp = (IList<QueryParameter>)qry.parameters;
Throws
Test method MoleSVSTest.MoleSVCTester.MoleSVCTestMethod threw exception: NHibernate.LazyInitializationException: Initializing[nha.cs.utility.mole.Query#24]-failed to lazily initialize a collection of role: nha.cs.utility.mole.Query.parameters, no session or session was closed
public class Query
{
public virtual int id { get; protected set; }
public virtual string name { get; set; }
public virtual string query { get; set; }
public virtual IList<QueryParameter> parameters { get; set; }
public virtual IList<Application> applicationsUsedIn { get; set; }
public Query()
{
this.parameters = new List<QueryParameter>();
this.applicationsUsedIn = new List<Application>();
}
public virtual void AddParameter(QueryParameter qp)
{
qp.query = this;
this.parameters.Add(qp);
}
}
public class QueryMap : ClassMap<Query>
{
public QueryMap()
{
Table("dbo.Queries");
Id(x => x.id);
Map(x => x.name);
Map(x => x.query);
HasMany(x => x.parameters)
.Cascade.All()
.KeyColumn("qryid")
.LazyLoad()
;
HasManyToMany(x => x.applicationsUsedIn)
.Table("dbo.ApplicationsQueries")
.ParentKeyColumn("qryid")
.ChildKeyColumn("appid")
.Inverse()
.LazyLoad()
;
}
}
public XmlNode runQuery(string appnname, string qryname, List<String> parms)
{
XmlNode xn = null;
if ((null != appnname) && (appnname.Length > 0))
{
if ((null != qryname) && (qryname.Length > 0))
{
Query qry = md.getQuery(appnname, qryname);
if (null != qry)
{
if ((null != parms) && (parms.Count > 0)) //Passed parameters as List<String>
{
//These are the three lines I have tried
IList<QueryParameter> lqp = (IList<QueryParameter>)qry.parameters;
List<QueryParameter> lqp = qry.parameters.ToList<QueryParameter>();
List<QueryParameter> lqp = new List<QueryParameter>(qry.parameters);
...
...
...
Updated with QueryParameter class and map.
public class QueryParameter
{
public virtual int id { get; set; }
public virtual Query query { get; set; }
public virtual string name { get; set; }
public virtual MOLEDataTypes type { get; set; }
public virtual int order { get; set; }
public QueryParameter()
{
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as QueryParameter;
if (t == null)
return false;
if (query == t.query && name == t.name)
return true;
return false;
}
public override int GetHashCode()
{
return (query.id + "|" + name).GetHashCode();
}
}
public class QueryParametersMap : ClassMap<QueryParameter>
{
public QueryParametersMap()
{
Table("dbo.QueryParameters");
Id(x => x.id);
References(x => x.query).Column("qryid").Not.Insert();
Map(x => x.name);
Map(x => x.type).CustomType<MOLEDataTypes>();
Map(x => x.order).Column("ordr");
}
}
More Code
public Query getQuery(string appname, string qryname)
{
Query retq = null;
using (ISessionFactory isf = getSessionFactory())
{
using (var sess = isf.OpenSession())
{
using (var tran = sess.Transaction)
{
try
{
tran.Begin();
...
USING session
...
}
catch (Exception ex)
{
tran.Rollback();
sess.Close();
lws.logMessage(AppName, "getQuery", ex.ToString(), MessageType.Error, MessageLevel.Error);
}
}
}
}
return (retq);
}
Any hints or suggestions you might have would be greatly appreciated.
Thanks,
Bruce.