Я пытаюсь написать несколько общих запросов LINQ для моих сущностей, но у меня возникают проблемы при выполнении более сложных задач. Прямо сейчас я использую класс EntityDao, который имеет все мои дженерики, и каждый из моих классов объектов Daos (например, Accomplishments Dao) наследует его, например:
using LCFVB.ObjectsNS;
using LCFVB.EntityNS;
namespace AccomplishmentNS
{
public class AccomplishmentDao : EntityDao<Accomplishment>{}
}
Теперь мой entityDao имеет следующий код:
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;
}
}
}
}
Я получил работающую функцию insertRow, однако я даже не уверен, как поступить с getOnebyValueOfProperty, самая близкая вещь, которую я мог найти на этом сайте, была:
Общий LINQ TO SQL-запрос
Как я могу передать имя столбца и значение, которое я проверяю, в общем, используя мою текущую настройку? По этой ссылке кажется, что это невозможно, поскольку используется предикат where, потому что класс сущности не знает, что это за свойства, пока я не передам их.
Наконец, мне нужен какой-то способ установки нового объекта в качестве типа возвращаемого значения, установленного для типа реализации, в nhibernate (из которого я пытаюсь преобразовать) это была просто эта строка, которая сделала это:
ImplentationType entity = default(ImplentationType);
Однако по умолчанию это команда nhibernate, как бы я это сделал для LINQ?
EDIT:
getOne не работает даже при выходе из базового класса (это частичный класс автоматически сгенерированных классов LINQ). Я даже удалил дженерики. Я попробовал:
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;
}
}
}
Получите следующую ошибку:
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
Хорошо, нет проблем, я изменил:
public Accomplishment getOneByWhereClause(Expression<Action<Accomplishment, bool>> singleOrDefaultClause)
до:
public Accomplishment getOneByWhereClause(Expression<Func<Accomplishment, bool>> singleOrDefaultClause)
Ошибка исчезает. Хорошо, но теперь, когда я пытаюсь вызвать метод через:
Accomplishment accomplishment = new Accomplishment();
var result = accomplishment.getOneByWhereClause(x=>x.Id = 4)
Это не работает, говорит, что x не объявлено.
я тоже пробовал
getOne<Accomplishment>
Expression<Func<
Expression<Action<
в различных форматах, но либо параметры не распознаются правильно как выражение в вызове функции, либо он не может преобразовать тип, который у меня есть в качестве параметра, в тип, используемый внутри singleofDefault (). Так что обе ошибки, как и выше. И у достижения класса есть идентификатор. Наконец, я также попытался объявить x новым достижением, чтобы оно было объявлено, после чего код автоматически изменяет => на> = и говорит:
Error 1 Operator '>=' is not defined for types 'LCFVB.ObjectsNS.Accomplishment' and 'Integer'.
= (