我收到了一个看起来相当简单的QueryOver的错误。复杂的是,选择涉及一个CompositeId。nhibernate查询compositeid异常
我得到的错误是:
System.InvalidOperationException:变量 'X' 类型的 'nha.cs.utility.mole.QueryParameters' 从范围'refrenced,但 不定义。
我正在映射具有许多查询参数的查询。复合标识符包含查询和查询参数名称,如下所示。
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<QueryParameters> parameters { get; set; }
public virtual IList<Application> applicationsUsedIn { get; set; }
public Query()
{
this.parameters = new List<QueryParameters>();
this.applicationsUsedIn = new List<Application>();
}
public virtual void AddParameter(QueryParameters qp)
{
qp.query = this;
this.parameters.Add(qp);
}
}
public class QueryParameters
{
public virtual Query query { get; set; }
public virtual string name { get; set; }
public virtual string type { get; set; }
public virtual int order { get; set; }
public QueryParameters()
{
}
public QueryParameters(Query qry, string nm)
{
this.query = qry;
this.name = nm;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
var t = obj as QueryParameters;
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 QueryMap()
{
Table("dbo.Queries");
Id(x => x.id);
Map(x => x.name);
Map(x => x.query);
HasMany(x => x.parameters)
.Cascade.All()
;
HasManyToMany(x => x.applicationsUsedIn)
.Table("dbo.ApplicationsQueries")
.ParentKeyColumn("qryid")
.ChildKeyColumn("appid")
.Inverse()
.LazyLoad();
}
public QueryParametersMap()
{
Table("dbo.QueryParameters");
CompositeId()
.KeyReference(x => x.query)
.KeyProperty(x => x.name)
;
References(x => x.query).Column("qryid").Not.Insert();
Map(x => x.name);
Map(x => x.order);
Map(x => x.type);
}
public Query addParameterToQuery(Query qry, string paramname, string paramtype, int paramorder)
{
if (null != qry)
{
string qryname = qry.name;
string qrystr = qry.query;
using (ISessionFactory isf = getSessionFactory())
{
using (var sess = isf.OpenSession())
{
using (var tran = sess.Transaction)
{
try
{
tran.Begin();
var critqry = sess.CreateCriteria<Query>()
.Add(Restrictions.Eq("name", qryname));
Query qryd = (Query)critqry.UniqueResult();
if (null == qryd)
{
qryd = new Query();
qryd.name = qryname;
qryd.query = qrystr;
sess.Save(qryd);
Console.Out.WriteLine("Query was null, added new query with name '" + qryname + "'");
}
else
{
Console.Out.WriteLine("Query was not null, has name '" + qryname + "'");
}
//EXCEPTION THROWN ON THIS LINE BELOW
var cp = sess.QueryOver<QueryParameters>()
.Select(x => x.query == qryd, x => x.name == paramname);
QueryParameters qryparam = cp.List().First<QueryParameters>();
}
catch (Exception ex)
{
tran.Rollback();
lws.logMessage(AppName, "addParameterToQuery", ex.ToString(), MessageType.Info, MessageLevel.Error);
Console.Out.WriteLine(ex.ToString());
}
}
}
}
}
return (null);
}
任何想法或指针将不胜感激。
谢谢,
布鲁斯。
更新的代码
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");
HasManyToMany(x => x.applicationsUsedIn)
.Table("dbo.ApplicationsQueries")
.ParentKeyColumn("qryid")
.ChildKeyColumn("appid")
.Inverse()
.LazyLoad();
}
}
public class QueryParametersMap : ClassMap<QueryParameters>
{
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);
Map(x => x.order).Column("ordr");
}
}
var cp = sess.QueryOver<QueryParameters>()
.Where(x => x.query.id == qryd.id)
.And(x => x.name == paramname);
Radim,非常感谢你的帮助。我也接受了您的建议并创建了一个主键,它解决了我遇到的其他问题,并简化了我的代码。 –
我确实需要向父级(查询)添加一个'KeyColumn'来修复由此产生的无效列名。固定代码张贴在上面 –
看到这一切真是太棒了。 NHibernate绝对不容易学习,进入。真的不是。但后来...;) –