У меня есть модель клиента, который имеет множество свойств, такие как имя, фамилия, адрес, ...Создание ICriterion перебирая свойства через PropertyInfo для NHibernate сессии
Через ClientEditViewModel я могу изменить значение свойств в TextBoxes.
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: Ауф умирают переменной "с" ВОМ Typ "Rechnungsprogramm.Model.Client" вирда Bereich вом "" verwiesen, Sie ист jedoch Nicht definiert.
System.InvalidOperationException: переменная 'с' типа '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;
}
Ah ok thank you @ Frédéric :) Я попробую его с помощью динамического выражения 'Expression' –
. Берегитесь, вы не можете напрямую использовать динамику Microsoft, так как это для LINQ, для которого [tag: queryover] нет. Вам нужно будет переключиться на [tag: linq-to-nhibernate], чтобы использовать его. Но вы можете изучить его реализацию, чтобы найти, как создавать свои собственные выражения динамически. (Чтение ссылок этого [ответа] (http://stackoverflow.com/a/1292639/1178314) может быть более простым). –