Sachin Prasad
Sachin Prasad

Reputation: 5411

Nhibernate Linq Get<T> object by name not by Id

public T FindById(object id)
{
     return session.Get<T>(id);
}

I want to get object by Name

Something like this, but I am not able to write a query with type T

session.Get<T>().Where(x => x.something == something).SingleOrDefault();

or is there any alternative to this approach?

Upvotes: 1

Views: 2312

Answers (5)

Najera
Najera

Reputation: 2879

Im not sure what you mean by "I am not able to write a query with type T". But you can call with expression where refactor is supported.

public T GetByExpression<T>(Expression<Func<T, bool>> restriction) where T : class
{
    return Session.QueryOver<T>().Where(restriction).SingleOrDefault();
}

Upvotes: 0

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

There is a native solution in NHiberante:

Chapter 15. Criteria Queries

This Criteria API (which is there from the beginning) is really what we need here. For example the QueryOver API - is built on top of that.

The biggest benefit is, it does work natively with "strings". This would be very simple, easy to maintain piece of code:

public T GetByProperty<T>(string propertyName, object value)
    where T: class
{
    var session = ... // get a session
    return session.CreateCriteria<T>()
        .Add(Restrictions.Eq(propertyName, value))
        .SetMaxResults(1)
        .List<T>()
        .FirstOrDefault();
}

There is a complete doc

Upvotes: 2

xanatos
xanatos

Reputation: 111860

You can use Expression trees and build something like:

protected T Get<T, TValue>(string propertyName, TValue value) where T : class
{
    var par = System.Linq.Expressions.Expression.Parameter(typeof(T), "x");
    var eq = System.Linq.Expressions.Expression.Equal(System.Linq.Expressions.Expression.Property(par, propertyName), System.Linq.Expressions.Expression.Constant(value));
    var lambda = System.Linq.Expressions.Expression.Lambda<Func<T, bool>>(eq, par);
    return session.QueryOver<T>().Where(lambda).SingleOrDefault();
}

Note that I'm using the full namespace + classname because NHibernate has another Expression class.

Upvotes: 3

Francisco Mercedes
Francisco Mercedes

Reputation: 107

I think you should use reflection for query a generic type, just like this:

session.Get<T>().Where(P => typeof(P).GetPropery("PropertyName").GetValue(P).ToString() == "Something").SingleOrDefault();

In this code, typeof(oObject) returns de a Type intance of the object, then the GetProperty("PropertyName") method returns you a System.Reflection.PropertyInfo with that you can get the property value with GetValue(P) method that receive an instance of the object that contain the property in this case is [P] create in Lamba expression.

Upvotes: 1

simon at rcl
simon at rcl

Reputation: 7344

You have to restrict T to something with a particular property. You could, for instance, create a superclass called NamedObject which has a property Name and make all nameable objects inherit from it. Restricting T to a NameableObject or descendant would then allow you to access the Name property in your query.

Not particularly elegant but it should work.

Upvotes: 1

Related Questions