我正在使用nHibernate并且正在尝试填充一个实体,该实体具有来自存储过程的另一个实体的子类。我有一个RankedListing,其中包含Id,Rank和a Listing
public class RankedListing : DomainEntity
{
public virtual int Id { get; set; }
public virtual int Rank { get; set; }
public virtual Listing Listing { get; set; }
}
我正在调用存储过程来从FULLTEXT
搜索填充此实体。存储过程返回三列(Id,Rank和Listing_Id)。我正在执行的代码如下。
IQuery query = ServiceLocator.Current.GetInstance<INHibernateUnitOfWork>().CurrentSession.CreateSQLQuery("exec dbo.usp_SearchListings :Search");
query.SetString("Search", search);
var products = query.SetResultTransformer(Transformers.AliasToBean(typeof(RankedListing))).List<RankedListing>().ToList();
return products;
当我执行此操作时,我得到的错误是:
Could not find a setter for property 'Listing_Id' in class 'RankedListing'
无论如何都要将它映射到RankedListing上的列表,而不是试图将它作为列名称映射为属性。
答案 0 :(得分:2)
我不知道这是最好的方式,但是自定义结果转换器可以做到
class MyTransformer : IResultTransformer
{
private ISession _session;
private Dictionary<int, int> _listingIds = new Dictionary<int, int>();
public MyTransformer(ISession session)
{
_session = session;
}
public IList TransformList(IList collection)
{
var listings = _session.QueryOver<Listing>()
.WhereRestrictionOn(l => l.Id).IsIn(_listingIds.Values)
.List().ToDictionary(l => l.Id);
return collection.Cast<RankedListing>()
.Select(rl => { rl.Listing = listings[_listingIds[rl.Id]]; return rl; })
.ToList();
}
public object TransformTuple(object[] tuple, string[] aliases)
{
var rl = new RankedListing();
rl.Id = (int)tuple[System.Array.FindIndex(aliases, name => name == "Id")];
rl.Rank = (int)tuple[System.Array.FindIndex(aliases, name => name == "Rank")];
_listingIds.Add(rl.Id, (int)tuple[System.Array.FindIndex(aliases, name => name == "Listing_Id")]);
return rl;
}
}
然后使用它:
var products = query.SetResultTransformer(new MyTransformer(CurrentSession)).List<RankedListing>();
更新:如果您想延迟加载列表,也可以
.Select(rl => { rl.Listing = session.Load<Listing>(_listingIds[rl.Id]); return rl; })