2010-12-13 10 views
3

nHibernate v。2.1.2.4、nHibernate.Linq v。1.1.0.1001、およびFluent NHibernate v。1.1.0.685を使用したFluent nHibernate。LINQ to NHibernate:プロパティを解決できませんでした

私はDateOfEventと呼ばれるDateTimeフィールドを持つドメインオブジェクトを持っています。これはデータベースの実際の日付/時刻フィールドです。また、DateOfEventフィールドからYearを取得する2つの新しいプロパティYearOfEventと、DateOfEventフィールドからMonthを取得するMontOfEventを追加しました。しかし

public class Event 
{ 
    public Event() { } 
    public virtual Int32 Id { get; set; } 
    public virtual String Title { get; set; } 
    public virtual DateTime DateOfEvent { get; set; } 
    public virtual Int32 YearOfEvent 
    { 
     get { return DateOfEvent.Year; } 
    } 
    public virtual Int32 MonthOfEvent 
    { 
     get { return DateOfEvent.Month; } 
    } 
    public virtual String Location { get; set; } 
    public virtual String City { get; set; } 
    public virtual String State { get; set; } 
    public virtual String Zip { get; set; } 
    public virtual String Description { get; set; } 
    public virtual Boolean HasImage { get; set; } 
    public virtual Boolean IsActive { get; set; } 
} 

、この方法を実行している:

public IList<Event> GetActiveEvents(int pageNumber, int pageSize, out int totalItems) 
    { 
     Int32 skip = Misc.NumberToSkip(pageNumber, pageSize); 
     totalItems = (from e in _session.Linq<Event>() 
         where e.IsActive 
         select e).Count(); 

     return (from e in _session.Linq<Event>() 
       where e.IsActive 
       select e) 
      .Skip(skip) 
      .Take(pageSize) 
      .ToList(); 
    } 

NHibernate.QueryException:プロパティを解決できませんでした:YearOfEventの:....イベント

FWIW、私はぼやけてきましたプロジェクトの名前。 ;)

どのようにこのクエリを動作させるためのアイデアですか?

ありがとうございます! -Steve

EDIT: ここに私のマッピングクラスがあります:

public class EventMap : ClassMap<Event> 
{ 
    public EventMap() 
    { 
     Table("tbl_event"); 
     Id(x => x.Id, "eventId"); 
     Map(x => x.DateOfEvent, "dateOfEvent"); 
     Map(x => x.Description, "description"); 
     Map(x => x.Title, "title"); 
     Map(x => x.Location, "location"); 
     Map(x => x.State, "state"); 
     Map(x => x.City, "city"); 
     Map(x => x.Zip, "zip"); 
     Map(x => x.HasImage, "hasImage"); 
     Map(x => x.IsActive, "isActive"); 
    } 
} 

...と私の設定:

public Configuration GetConfiguration() 
    { 
     Configuration configuration; 
     var assembly = Assembly.Load(".....Data"); 
     var fluentConfig = Fluently.Configure() 
          .Database(MySQLConfiguration.Standard.ConnectionString(
              c => c.FromConnectionStringWithKey("......") 
             )) 
          .Mappings(m => m.FluentMappings.AddFromAssembly(assembly)); 
     configuration = fluentConfig.BuildConfiguration(); 
     configuration.Properties.Add("hbm2ddl.keywords", "none"); 
     return configuration; 
    } 

私もちょうどクライテリアAPIを試してみました:

return _session.CreateCriteria(typeof (Event)) 
      .Add(Expression.Eq("IsActive", true)) 
      .Add(Expression.Eq("YearOfEvent", year)) 
      .List<Event>(); 

ワークリーもありません。

+0

あなたのマップを投稿してください –

+0

Strange。私にはうまく見えますが、LINQプロバイダがプロパティで何か魅力的なことをしようとしているのだろうかと思います。 LINQなしで同じクエリを実行しようとしましたか? – Phill

+0

Phill、Criteria APIを使用して試しました。同じ例外です。 – StephenPAdams

答えて

4

ここでは、数式を使用して修正する方法を示します。あなたのイベントクラスでは、これら2つのプロパティを通常のプロパティに変換します:

public class Event 
{ 
    public Event() { } 
    ... 
    public virtual DateTime DateOfEvent { get; set; } 
    public virtual Int32 YearOfEvent{ get; set; } 
    public virtual Int32 MonthOfEvent { get; set; } 
    ... 
    public virtual Boolean IsActive { get; set; } 
} 

次に、マッピングで式を追加して値を設定します。

public class EventMap : ClassMap<Event> 
{ 
    public EventMap() 
    { 
     Table("tbl_event"); 
     Id(x => x.Id, "eventId"); 
     Map(x => x.DateOfEvent, "dateOfEvent"); 
     Map(x => x.YearOfEvent).Formula("SELECT YEAR(dateOfEvent)"); 
     Map(x => x.MonthOfEvent).Formula("SELECT MONTH(dateOfEvent)");    
     ... 
     Map(x => x.IsActive, "isActive"); 
    } 
} 

は今、あなただけのLINQのいずれかを使用して、他の分野のようにそれらを照会することができます:私は年&月取り出すためのMySQLの構文について非常に肯定的ではないですが、あなたはアイデアを持っている(私はthisリファレンスを使用しました)またはICriteria:私が使用

return _session.CreateCriteria(typeof (Event)) 
      .Add(Expression.Eq("IsActive", true)) 
      .Add(Expression.Eq("YearOfEvent", year)) 
      .List<Event>(); 
+0

ありがとう、デニス! – StephenPAdams

1

自動マッピングですか?私はそれがYearOfEventとMonthOfEventをマップしようとしていると思われ、データベースからそれらの列を取得しようとしていますが、それらは存在しません。

手動でマッピングしている場合は問題ありません。

+0

Phill、私はそれらを手動でマッピングしています。私は自分の設定とそのマッピングを投稿しました。 – StephenPAdams

2

データベースに実際に存在するか、マッピングに導入されたプロパティをクエリできます。エンティティにはYearOfEventが存在するだけなので、LINQ-NHまたはICriteriaのクエリでは使用できません。

0

"YearOfEvent"プロパティがマッピングに表示されていないため、条件クエリが機能していません。 NHibernateはこのプロパティを知らず、カラム名に変換することはできません。

はしかし、それは動作するはずのようなあなたのLINQクエリが見え、私はどのように表示されていない...実際に計算プロパティの代わりにマッピングされた、またはあなたのクエリでプロパティを直接計算されているプロパティを照会

をお試しくださいこのエラーはこのクエリで発生する可能性があります&マッピング...

2

技術はNHLinqの実行を強制して、フィルタリングを完了するためにLINQを利用することです。 NHはEvent.YearOfEventのようなマップされていないプロパティを認識していないので、これは技術的には何が起こる必要があります。

_session.Linq<Event>() 
.Where(e => e.IsActive) 
.ToArray() // force evaluation of expression 
.Where(e => e.YearOfEvent == DateTime.Now.Year); // evaluated by LINQ, not NHLinq 

注:評価を強制するその他の方法(ToList()など)を利用することができます。この手法はToArray()には特に依存しません。