mardi 31 janvier 2017

Create ICriterion by iterating through properties via PropertyInfo for NHibernate session

I've got a client model that has many properties like first name, last name, address, ...

Via the ClientEditViewModel I can change the property values in 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); }
    }

    ...
}

When the user is pressing the search button, I want to iterate through all properties. If the property is not empty or null, I want to add them to the query with the 'LIKE' restriction. Instead of checking every property manually, I wanted to iterate all properties via 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;
}

Unfotunately, when I use this conjunction in the following code, I get an error. How can I iterate through all my properties without checking every single property manually?

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: Auf die Variable "c" vom Typ "Rechnungsprogramm.Model.Client" wird vom Bereich "" verwiesen, sie ist jedoch nicht definiert.

System.InvalidOperationException: variable 'c' of type 'Rechnungsprogramm.Model.Client' referenced from scope '', but it is not defined





Aucun commentaire:

Enregistrer un commentaire