Как запросить составной первичный ключ с помощью Fluent NHibernate и QueryOver? - PullRequest
0 голосов
/ 05 декабря 2011

У меня есть список Funds, каждый из которых имеет ID, ConfigID и CountryID.Мне нужно выбрать FundPerformances для каждого Fund на основе этих идентификаторов.

Таблица FundPerformance имеет составной первичный ключ ID, ConfigID & CountryID.

Пока у меня есть

perfs = _session.QueryOver<FundPerformance>()
            .Where(xx => xx.ConfigId == _configId)
            .Where(Restrictions.In(Projections.Property<FundPerformance>(t => t.Id), funds.Select(xx => xx.Id).ToArray()))
            .Where(Restrictions.In(Projections.Property<FundPerformance>(t => t.CountryId), funds.Select(xx => xx.CountryId).ToArray()))
            .List<FundPerformance>().ToList();

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

Что мне делатьнужно сделать, чтобы правильно выбрать данные?

Это текущий класс сопоставления FundPerformance:

public class FundPerformanceMap : ClassMap<FundPerformance>
{
    public FundPerformanceMap()
    {
        Id(x => x.Id).Column("FundPerformanceStatistics_FundId");
        Map(x => x.CountryId).Column("FundPerformanceStatistics_FundCountryId");
        Map(x => x.ConfigId).Column("FundPerformanceStatistics_ConfigId");

        Map(x => x.OneMonth).Column("FundPerformanceStatistics_OneMonthBack");
        Map(x => x.ThreeMonth).Column("FundPerformanceStatistics_ThreeMonthBack");
        Map(x => x.YTD).Column("FundPerformanceStatistics_YearToDate");
    }
}

1 Ответ

1 голос
/ 05 декабря 2011

Может быть, вы ищете что-то еще

public class Fund
{
    public virtual int Id { get; set; }
    public virtual Country Country { get; set; }

    public virtual Config Config { get; set; }

    public virtual IDictionary<Config, FundPerformance> Performances { get; private set; }
    public virtual FundPerformance ActualPerformance { get { return Performances[Config]; } }

}

public class FundPerformance
{
    public virtual Fund Fund { get; set; }
    public virtual Config Config { get; set; }

    public virtual int OneMonth { get; set; }
    public virtual int ThreeMonth { get; set; }
    public virtual int YTD { get; set; }
}

public class Config
{
    public virtual int Id { get; set; }
}

public class FundMap : ClassMap<Fund>
{
    public FundMap()
    {
        CompositeId()
            .KeyProperty(x => x.Id, "FundId")
            .KeyProperty(x => x.CountryId, "FundCountryId");

        HasMany(x => x.Performances)
            .KeyColumns.Add("FundPerformanceStatistics_FundId", "FundPerformanceStatistics_FundCountryId")
            .AsMap(fp => fp.Config)
            .Cascade.AllDeleteOrphan()
            .Component(c =>
            {
                c.ParentReference(x => x.Fund);
                c.References(x => x.Config, "FundPerformanceStatistics_ConfigId");
                c.Map(x => x.OneMonth, "FundPerformanceStatistics_OneMonthBack");
                c.Map(x => x.ThreeMonth, "FundPerformanceStatistics_ThreeMonthBack");
                c.Map(x => x.YTD, "FundPerformanceStatistics_YearToDate");
            })
    }
}

// Query
var someCountry = session.Load<Country>(5); <- get the Country with id 5 without going to the db (proxy when not already loaded) only to have the reference

var key = new Fund { Id = 1, Country = someCountry }
var fund = session.Get<Fund>(key);
var performanceByConfig = fund.Performances[_config];

Оригинальный ответ:

если у Fund есть составной ключ, то у FundPerformance тоже должен быть один.Также я думаю, что Ссылка на Фонд более похожа на ООП:

public class FundPerformance
{
    public virtual Fund Fund { get; set; }

    public virtual int OneMonth { get; set; }
    public virtual int ThreeMonth { get; set; }
    public virtual int YTD { get; set; }
}

Либо сопоставьте его как Компонент (потому что он выглядит как нечто зависимое)

public class FundMap : ClassMap<Fund>
{
    public FundMap()
    {
        CompositeId()
            .KeyProperty(x => x.Id, "FundId")
            .KeyProperty(x => x.CountryId, "FundCountryId")
            .KeyProperty(x => x.ConfigId, "ConfigId");

        HasMany(x => x.Performances)
            .KeyColumns.Add("FundPerformanceStatistics_FundId", "FundPerformanceStatistics_FundCountryId", "FundPerformanceStatistics_ConfigId")
            .Cascade.AllDeleteOrphan()
            .Component(c =>
            {
                c.ParentReference(x => x.Fund);
                c.Map(x => x.OneMonth, "FundPerformanceStatistics_OneMonthBack");
                c.Map(x => x.ThreeMonth, "FundPerformanceStatistics_ThreeMonthBack");
                c.Map(x => x.YTD, "FundPerformanceStatistics_YearToDate");
            })
    }
}

, либо как сущность с составнымключ

public class FundPerformanceMap : ClassMap<FundPerformance>
{
    public FundPerformanceMap()
    {
        CompositeId()
            .KeyReference(x => x.Fund, param => param
                .Column("FundPerformanceStatistics_FundId")
                .Column("FundPerformanceStatistics_FundCountryId")
                .Column("FundPerformanceStatistics_ConfigId"));

        Map(x => x.OneMonth).Column("FundPerformanceStatistics_OneMonthBack");
        Map(x => x.ThreeMonth).Column("FundPerformanceStatistics_ThreeMonthBack");
        Map(x => x.YTD).Column("FundPerformanceStatistics_YearToDate");
    }
}

// Query
var key = new Fund { Id = 1, CountryId = 2, ConfigId = 3}
var fund = session.Get<Fund>(key);
var performances = fund.Performances;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...