2017-01-31 3 views
0

NHibernateのセッションのためのPropertyInfoを経由してプロパティを反復処理することにより、私はプロパティの値を変更することができますClientEditViewModel経由して...私は姓、名、住所、などの多くのプロパティを持っているクライアントモデルを持っている

をICriterionを作成します。テキストボックス内。

public class ClientEditViewModel : EditableViewModelBase 
{ 
    public int ClientID 
    { 
     get { return this.currentClient.ClientID; } 
     set { this.SetProperty(newValue => this.currentClient.ClientID = newValue, value); } 
    } 

    public string Title 
    { 
     get { return this.currentClient.Title; } 
     set { this.SetProperty(newValue => this.currentClient.Title = newValue, value); } 
    } 

    public string FirstName 
    { 
     get { return this.currentClient.FirstName; } 
     set { this.SetProperty(newValue => this.currentClient.FirstName = newValue, value); } 
    } 

    public string LastName 
    { 
     get { return this.currentClient.LastName; } 
     set { this.SetProperty(newValue => this.currentClient.LastName = newValue, value); } 
    } 

    ... 
} 

ユーザーが検索ボタンを押すと、すべてのプロパティを反復処理します。プロパティが空でないかヌルでない場合、それらを 'LIKE'制限付きのクエリに追加したいと思います。すべてのプロパティを手動でチェックするのではなく、Reflectionですべてのプロパティを繰り返したいと思っていました。

public ICriterion GetSearchClientCriteria() 
{ 
    var conjunction = Restrictions.Conjunction(); 

    if (this.ClientID != 0) 
    { 
     conjunction.Add(Restrictions.Where<Client>(x => x.ClientID == this.ClientID)); 
     return conjunction; 
    } 

    foreach (PropertyInfo propertyInfo in this.PropertyInfosWithPublicGetterAndSetter) 
    { 
     if (propertyInfo.PropertyType == typeof(string)) 
     { 
      string currentPropertyValue = propertyInfo.GetValue(this) as string; 

      if (!string.IsNullOrEmpty(currentPropertyValue)) 
      { 
       /* This statement can be executed */ 
       // conjunction.Add(Restrictions.Where<Client>(c => c.FirstName.IsLike(this.FirstName, MatchMode.Anywhere))); 
       conjunction.Add(Restrictions.Where<Client>(c => c.GetType().GetProperty(propertyInfo.Name).GetValue(c, null).ToString() 
       .IsLike(this.GetType().GetProperty(propertyInfo.Name).GetValue(this).ToString()))); 

       return conjunction; 
      } 
     } 
    } 

    return conjunction; 
} 

このコードを次のコードで使用すると、エラーが発生します。すべてのプロパティを手動でチェックせずにすべてのプロパティを繰り返し処理するにはどうすればよいですか?

public class NHibernateRepository : IRepository 
{ 
    public ICollection<T> GetByCriteria<T>(ICriterion criterion) where T : class 
    { 
     using (var session = this.sessionManager.OpenSession()) 
     { 
      return session.QueryOver<T>().Where(criterion).List(); 
     } 
    } 
} 

のSystem.InvalidOperationException:アウフは "変数 "C" VOM標準 "Rechnungsprogramm.Model.Client" wirdのVOM Bereichダイ" verwiesen、SIEイストjedoch NICHTのdefiniert。

のSystem.InvalidOperationException:変数 'C' タイプの 'Rechnungsprogramm.Model.Client' '' は範囲から を参照し、それは

独自のソリューション

定義されない:

最も良い解決策ではありませんが、機能します。

private ICriterion GetClientSearchCriterion() 
{ 
    Conjunction conjunction = Restrictions.Conjunction(); 

    if (this.CurrentClientDetailViewModel.ClientId != 0) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.ClientId == this.CurrentClientDetailViewModel.ClientId)); 
     return conjunction; 
    } 

    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.Title)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.Title.IsLike(this.CurrentClientDetailViewModel.Title, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.FirstName)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.FirstName.IsLike(this.CurrentClientDetailViewModel.FirstName, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.LastName)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.LastName.IsLike(this.CurrentClientDetailViewModel.LastName, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.Street)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.Street.IsLike(this.CurrentClientDetailViewModel.Street, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.HouseNumber)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.HouseNumber.IsLike(this.CurrentClientDetailViewModel.HouseNumber, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.PostalCode)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.PostalCode.IsLike(this.CurrentClientDetailViewModel.PostalCode, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.City)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.City.IsLike(this.CurrentClientDetailViewModel.City, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.DateOfBirth)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.DateOfBirth.IsLike(this.CurrentClientDetailViewModel.DateOfBirth, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.PhoneNumber1)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.PhoneNumber1.IsLike(this.CurrentClientDetailViewModel.PhoneNumber1, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.PhoneNumber2)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.PhoneNumber2.IsLike(this.CurrentClientDetailViewModel.PhoneNumber2, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.MobileNumber)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.MobileNumber.IsLike(this.CurrentClientDetailViewModel.MobileNumber, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.Telefax)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.Telefax.IsLike(this.CurrentClientDetailViewModel.Telefax, MatchMode.Anywhere))); 
    } 
    if (!string.IsNullOrEmpty(this.CurrentClientDetailViewModel.Email)) 
    { 
     conjunction.Add(Restrictions.Where<Client>(c => c.Email.IsLike(this.CurrentClientDetailViewModel.Email, MatchMode.Anywhere))); 
    } 

    return conjunction; 
} 

答えて

0

あなたは好きなものをラムダにORMによってSQLに変換する必要があります。
ラムダは、GetTypeGetPropertyGetValueなどと等価でないSQLに変換できる必要があります。

ラムダを使用する代わりに、Expressionを動的に作成してみてください。このようなビットはquestionと答えることができます。

+0

ああ、ありがとう@フレデリック: ダイナミックな「表現」で試してみよう –

+0

[タグ:クエリーオーバー]はLINQ用であるため、マイクロソフトのダイナミックスを直接使用することはできませんのでご注意ください。それを使用するには[tag:linq-to-nhibernate]に切り替える必要があります。しかし、独自の式を動的に構築する方法を見つけるための実装を検討することができます。 (この[answer](http://stackoverflow.com/a/1292639/1178314)のリンクを読む方がより簡単かもしれません。) –

関連する問題