问题描述
我有一个使用Fluent NHibernate的DAL,用于映射查询(作为字符串存储在db中)及其参数(存储在单独的表中).
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;
投掷
List<QueryParameter> lqp = qry.parameters.ToList<QueryParameter>();
投掷
List<QueryParameter> lqp = new List<QueryParameter>(qry.parameters);
投掷
IList<QueryParameter> lqp = (IList<QueryParameter>)qry.parameters;
投掷
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);
...
...
...
已更新为QueryParameter类和映射.
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");
}
}
更多代码
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.
谢谢
布鲁斯.
推荐答案
问题是您关闭了getQuery
中的会话,然后要求您的Query
对象的参数列表,NHibernate尝试加载该对象并由于缺少会话而失败.为了解决您的问题,您需要确保您的会话在整个请求中都处于打开状态,或者至少在所有业务交易完成之前保持打开状态.
The problem is that you close the session in getQuery
, and then ask for the list of parameters for your Query
object, which NHibernate tries to load and fails due to the absence of a session. To solve your problem, you need to ensure that your session is open throughout the request, or at least remains open until all business transactions have completed.
我建议您采用每次请求会话的方法.每当有网络请求时打开一个会话,并在会话结束时关闭它.使用Global.asax文件可以轻松实现此目的,您可以阅读此处.
I would suggest that you take a session-per-request approach. Open a session whenever there's a web request, and close it when the session ends. This can be achieved easily by using the Global.asax file, which you can read about here.
public class Global : System.Web.HttpApplication
{
public static ISessionFactory SessionFactory { get; private set; }
protected void Application_Start(object sender, EventArgs e)
{
// Create a session factory when the application starts.
// Session factories are expensive to create, and therefore you should create one and use it throughout your application.
SessionFactory = Fluently.Configure()
.Database(
SQLiteConfiguration.Standard
.UsingFile("firstProject.db")
)
.BuildSessionFactory();
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
// Create a session per request.
var session = SessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
}
protected void Application_EndRequest(object sender, EventArgs e)
{
// Close the session at the end of every request
var session = CurrentSessionContext.Unbind(SessionFactory);
session.Dispose();
}
protected void Application_End(object sender, EventArgs e)
{
// Close the session factory at the end of the application.
if (SessionFactory != null)
SessionFactory.Dispose();
}
}
在上面的示例中,在应用程序启动时会创建会话工厂,因此建议这样做,因为创建会话工厂的成本很高.然后,每个请求都会创建一个会话,并在最后放置会话.通过使用这种方法,由于所有操作都是自动完成的,因此您可以节省很多工作.
In the example above, a session factory is created when the application starts, which is recommended because it is costly to create a session factory. Then, a session is created every request, and disposed at the end. By using this approach, you save yourself a lot of work since everything is done automatically.
然后,要在代码中使用会话,您只需调用GetCurrentSession()
,如下所示:
Then, to use a session in your code, you would just need to call GetCurrentSession()
, like so:
var session = Global.SessionFactory.GetCurrentSession();
我希望这对您有所帮助,并祝您好运NHibernate.我建议您考虑阅读 NHibernate 3.0食谱,以便更好地理解NHibernate的.
I hope that helps, and best of luck fiddling with NHibernate. I would suggest you to consider reading the NHibernate 3.0 Cookbook for a better understanding of NHibernate.
这篇关于流利的NHibernate对象列表异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!