Заполнение сущностей из хранимой процедуры - PullRequest
0 голосов
/ 16 ноября 2011

Я использую nHibernate и пытаюсь заполнить сущность, у которой есть подкласс другой сущности из хранимой процедуры. У меня есть RankedListing, который содержит Id, Rank и 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 Ответ

2 голосов
/ 16 ноября 2011

Я не знаю, лучший ли это способ, но пользовательский преобразователь результатов мог бы сделать

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; })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...