如何使用 Fluent NHibernate 和 QueryOver 查询复合主键?

发布于 2024-12-20 00:30:31 字数 1507 浏览 2 评论 0原文

我有一个 Funds 列表,每个基金都有一个 IDConfigIDCountryID。我需要根据这些 ID 为每个Fund 选择FundPerformances

FundPerformance 表具有一个由 IDConfigIDID 组成的复合主键。 国家ID

到目前为止,我

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();

认为这不会起作用,因为它是在单个字段上进行选择,而不是在复合 ID 上进行选择。

我需要做什么才能正确选择数据?

这是当前的 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");
    }
}

I have a list of Funds, each of which has an ID, ConfigID and a CountryID. I need to select FundPerformances for each Fund, based on these IDs.

The FundPerformance table has a composite primary key of ID, ConfigID & CountryID.

So far, I have

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();

I don't think this is going to work because it's selecting on the individual fields, and not the composite ID.

What do I need to do to select the data properly?

This is the current FundPerformance mapping class:

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");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨巷深深 2024-12-27 00:30:31

也许您正在寻找其他东西

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 有一个 compositeKey,那么 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;

Maybe you are looking for something else

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];

Original answer:

if Fund has a compositeKey then FundPerformance should have one, too. Also i think a Reference to Fund is more OOP-like:

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; }
}

Either map it as Component (because it looks like something dependant)

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");
            })
    }
}

or as an Entity with composite key

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文