I am trying to write some generic LINQ queries for my entities, but am having issue doing the more complex things. Right now I am using an EntityDao class that has all my generics and each of my object class Daos (such as Accomplishments Dao) inherit it, am example:
using LCFVB.ObjectsNS;
using LCFVB.EntityNS;
namespace AccomplishmentNS
{
public class AccomplishmentDao : EntityDao<Accomplishment>{}
}
Now my entityDao has the following code:
using LCFVB.ObjectsNS;
using LCFVB.LinqDataContextNS;
namespace EntityNS
{
public abstract class EntityDao<ImplementationType> where ImplementationType : Entity
{
public ImplementationType getOneByValueOfProperty(string getProperty, object getValue)
{
ImplementationType entity = null;
if (getProperty != null && getValue != null) {
//Nhibernate Example:
//ImplementationType entity = default(ImplementationType);
//entity = Me.session.CreateCriteria(Of ImplementationType)().Add(Expression.Eq(getProperty, getValue)).UniqueResult(Of InterfaceType)()
LCFDataContext lcfdatacontext = new LCFDataContext();
//Generic LINQ Query Here
lcfdatacontext.GetTable<ImplementationType>();
lcfdatacontext.SubmitChanges();
lcfdatacontext.Dispose();
}
return entity;
}
public bool insertRow(ImplementationType entity)
{
if (entity != null) {
//Nhibernate Example:
//Me.session.Save(entity, entity.Id)
//Me.session.Flush()
LCFDataContext lcfdatacontext = new LCFDataContext();
//Generic LINQ Query Here
lcfdatacontext.GetTable<ImplementationType>().InsertOnSubmit(entity);
lcfdatacontext.SubmitChanges();
lcfdatacontext.Dispose();
return true;
}
else {
return false;
}
}
}
}
I have gotten the insertRow function working, however I am not even sure how to go about doing getOnebyValueOfProperty, the closest thing I could find on this site was:
http://stackoverflow.com/questions/2157560/generic-linq-to-sql-query
How can I pass in the column name and the value I am checking against generically using my current set-up? It seems like from that link it's impossible since using a where predicate because entity class doesn't know what any of the properties are until I pass them in.
Lastly, I need some way of setting a new object as the return type set to the implementation type, in nhibernate (what I am trying to convert from) it was simply this line that did it:
ImplentationType entity = default(ImplentationType);
However default is an nhibernate command, how would I do this for LINQ?
EDIT:
getOne doesn't seem to work even when just going off the base class (this is a partial class of the auto generated LINQ classes). I even removed the generics. I tried:
namespace ObjectsNS
{
public partial class Accomplishment
{
public Accomplishment getOneByWhereClause(Expression<Action<Accomplishment, bool>> singleOrDefaultClause)
{
Accomplishment entity = new Accomplishment();
if (singleOrDefaultClause != null) {
LCFDataContext lcfdatacontext = new LCFDataContext();
//Generic LINQ Query Here
entity = lcfdatacontext.Accomplishments.SingleOrDefault(singleOrDefaultClause);
lcfdatacontext.Dispose();
}
return entity;
}
}
}
Get the following error:
Error 1 Overload resolution failed because no accessible 'SingleOrDefault' can be called with these arguments:
Extension method 'Public Function SingleOrDefault(predicate As System.Linq.Expressions.Expression(Of System.Func(Of Accomplishment, Boolean))) As Accomplishment' defined in 'System.Linq.Queryable': Value of type 'System.Action(Of System.Func(Of LCFVB.ObjectsNS.Accomplishment, Boolean))' cannot be converted to 'System.Linq.Expressions.Expression(Of System.Func(Of LCFVB.ObjectsNS.Accomplishment, Boolean))'.
Extension method 'Public Function SingleOrDefault(predicate As System.Func(Of Accomplishment, Boolean)) As Accomplishment' defined in 'System.Linq.Enumerable': Value of type 'System.Action(Of System.Func(Of LCFVB.ObjectsNS.Accomplishment, Boolean))' cannot be converted to 'System.Func(Of LCFVB.ObjectsNS.Accomplishment, Boolean)'. 14 LCF
Okay no problem I changed:
public Accomplishment getOneByWhereClause(Expression<Action<Accomplishment, bool>> singleOrDefaultClause)
to:
public Accomplishment getOneByWhereClause(Expression<Func<Accomplishment, bool>> singleOrDefaultClause)
Error goes away. Alright, but now when I try to call the method via:
Accomplishment accomplishment = new Accomplishment();
var result = accomplishment.getOneByWhereClause(x=>x.Id = 4)
It doesn't work it says x is not declared.
I also tried
getOne<Accomplishment>
Expression<Func<
Expression<Action<
in various formats, but either the parameters are not recognized correctly as an expression in the function call, or it cannot convert the type I have as the parameter into the type used inside singleofDefault(). So both errors just like above. And the class accomplishment does have the ID. Finally I also tried declaring x as a new accomplishment so it would be declared, at which point the code changes the => to >= automatically and says:
Error 1 Operator '>=' is not defined for types 'LCFVB.ObjectsNS.Accomplishment' and 'Integer'.
=(