Как я могу написать пользовательское сравнение (определение для двоичного оператора Equal) для объекта entityframework с int?
Вопрос
Я получаю эту ошибку:
ex = {"Двоичный оператор Equal не определен для типов 'MySite.Domain.DomainModel.EntityFramework.Псевдоним' и 'System.Int32'".}
То, что я пытался сделать, это выбрать все, где NickNameId = someIntPassedIn
...проблема в том, что NickNameId является внешним ключом, поэтому, когда он сравнивает someIntPassedIn
к тому NickNameId
это тянет весь NickName
возражать против того, что NickNameId
ссылается на этот объект и пытается сравнить int с ним.
Мне нужно решение здесь, чтобы позволить ему сравнивать int с идентификатором объекта NickName ...итак
A) Как я могу определить двоичный оператор Equal для сравнения этих двух объектов
или
Б) Как я могу сравнить его непосредственно с идентификатором, а не со всем объектом?
Вам не обязательно читать это, но вот метод SelectAllByKey, если он поможет:
(Я ввел "NICKNAME id" и "1")
public IList<E> SelectAllByKey(string columnName, string key)
{
KeyProperty = columnName;
int id;
Expression rightExpr = null;
if (int.TryParse(key, out id))
{
rightExpr = Expression.Constant(id);
}
else
{
rightExpr = Expression.Constant(key);
}
// First we define the parameter that we are going to use the clause.
var xParam = Expression.Parameter(typeof(E), typeof(E).Name);
MemberExpression leftExpr = MemberExpression.Property(xParam, this._KeyProperty);
int temp;
BinaryExpression binaryExpr = MemberExpression.Equal(leftExpr, rightExpr);
//Create Lambda Expression for the selection
Expression<Func<E, bool>> lambdaExpr = Expression.Lambda<Func<E, bool>>(binaryExpr, new ParameterExpression[] { xParam });
//Searching ....
IList<E> resultCollection = ((IRepository<E, C>)this).SelectAll(new Specification<E>(lambdaExpr));
if (null != resultCollection && resultCollection.Count() > 0)
{
//return valid single result
return resultCollection;
}//end if
return null;
}
Дайте мне знать, если вам понадобится дополнительная информация.
Спасибо,
Мэтт
Решение
Ты должен позвонить SelectAllByKey('NickName.ID','1')
.
С тех пор как ID
является свойством свойства, вы могли бы использовать этот метод расширения:
public static MemberExpression PropertyOfProperty(this Expression expr,string propertyName)
{
var properties = propertyName.Split('.');
MemberExpression expression = null;
foreach (var property in properties)
{
if (expression == null)
expression = Expression.Property(expr, property);
else
expression = Expression.Property(expression, property);
}
return expression;
}
Другие советы
Общепринятый ответ кажется способ слишком сложно для рассматриваемой проблемы, если я правильно это читаю.
Если я вас правильно понял, вы пытаетесь выполнить запрос типа:
var q = from e in Context.SomeEntities
where e.NickNameId == someIntPassedIn
select e;
...но это не сработает, потому что e.NickNameId
является сущностью, а не целым числом.
Чтобы сослаться на Id
свойство, вы можете просто ссылаться на него, вот так:
var q = from e in Context.SomeEntities
where e.NickNameId.Id == someIntPassedIn
select e;
Обновить: Если вы не можете использовать строго типизированные свойства из-за вашего уровня абстракции (согласно вашему комментарию), то используйте методы построения запросов:
var q = (ObjectQuery<T>)Repository.SelectSomething();
return q.Where("it.NickName.Id = " + someIntPassedIn.ToString());
Вы можете адаптировать это по своему усмотрению, но общий смысл заключается в том, что EF уже знает, как переводить строки в члены свойства.