2011-12-05 12 views
0

私はFundsのリストを持っています。それぞれのリストはID,ConfigIDおよびCountryIDです。これらのIDに基づいて、FundごとにFundPerformancesを選択する必要があります。Fluent NHibernateとQueryOverを使用して複合主キーをどのようにクエリできますか?

FundPerformanceテーブルはIDConfigID & CountryIDの複合主キーを有します。

はこれまでのところ、私は、これは、それは個々のフィールドではなく、複合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(); 

を持っています。

データを正しく選択するために必要なことは何ですか?

これは、現在のFundPerformanceマッピングクラスである:たぶん、あなたは何か他のもの

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

オリジナルの答えを探している

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

基金はcompositeKeyを持っているならば、FundPerformanceは1を持っている必要があります、あまりにも。また、私は、基金への参照は、よりOOPのようだと思う:

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; 
+0

こんにちは@Firo、これのためにありがとう。申し訳ありませんが、私は今これだけに戻っていますが、今日のほとんどは他のものと結びついていました。私は少しでも混乱している。あなたは 'Fund'は' ConfigId'を含む 'CompositeId'マッピングを持つべきだと述べました。ファンドテーブルにConfigId列がないため、これが機能するかどうかはわかりません。それはFundPerformanceだけです。それは働くだろうか?あるいは、IDとCountryIDのFund CompositeIdマッピングを指定するだけでよいのですか? – DaveDev

+0

あなたの最初の文章「私にはID、ConfigID、CountryIDを持つファンドのリストがあります。あなたが持っていると思うようにしてください。それでは資金効率のconfigIdの目的は何ですか? – Firo

+0

申し訳ありません - 私はそれを混乱させるつもりはありませんでした。 FundPerformanceのConfigIDは、パフォーマンスの計算方法に関連しています。ファンドは、それが選択されるべきであるパフォーマンスを決定するために使用されるプロパティ構成IDを有する。 – DaveDev

関連する問題