Reputation: 5411
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
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
Reputation: 123861
There is a native solution in NHiberante:
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
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
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
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