从存储过程中填充实体

时间:2011-11-16 01:35:06

标签: nhibernate stored-procedures fluent-nhibernate

我正在使用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上的列表,而不是试图将它作为列名称映射为属性。

1 个答案:

答案 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; })