¿Cómo puedo escribir comparación personalizada (definición de operador binario Igualdad) para el objeto ADO.NET Entity Framework a un int?
Pregunta
Estoy recibiendo este error:
ex = { "El operador binario Equal no está definido para los tipos 'MySite.Domain.DomainModel.EntityFramework.NickName' y 'System.Int32'."}
Lo que intenté hacer fue hacer una selecta todo donde el NickNameId = someIntPassedIn
... el problema es que el NickNameId es una clave externa, por lo que cuando se compara el someIntPassedIn
a la NickNameId
se tira todo el objeto NickName
que el NickNameId
se refiere a y trata de comparar el int a ese objeto.
necesito una solución a este problema para que pueda comparar la int para el ID del objeto de apodo ... así
A) ¿Cómo puedo definir el operador binario de Igualdad para la comparación de estos dos objetos
o
B) ¿Cómo puedo comparar directamente a la ID en lugar de todo el objeto?
Usted no tiene que leer esto, pero aquí está el método SelectAllByKey encajona ayuda: gratis (pasé en "NickNameId" y "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;
}
Quiero saber si necesita más información.
Gracias,
Matt
Solución
Debe llamar SelectAllByKey('NickName.ID','1')
.
Desde ID
es característica de la propiedad, usted podría utilizar este método de extensión:
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;
}
Otros consejos
La respuesta aceptada parece manera demasiado complicado para el problema que nos ocupa, si estoy leyendo esto correctamente.
Si he entendido bien, usted está tratando de ejecutar una consulta como:
var q = from e in Context.SomeEntities
where e.NickNameId == someIntPassedIn
select e;
... pero esto no va a funcionar, porque e.NickNameId
es una entidad, no es un entero.
Para hacer referencia a la propiedad Id
, que acaba de hacer referencia a ella, como esto:
var q = from e in Context.SomeEntities
where e.NickNameId.Id == someIntPassedIn
select e;
Actualización: Si no puede utilizar propiedades fuertemente mecanografiada debido a su nivel de abstracción (por su comentario), a continuación, utilizar métodos generador de consultas :
var q = (ObjectQuery<T>)Repository.SelectSomething();
return q.Where("it.NickName.Id = " + someIntPassedIn.ToString());
Puede adaptar este como mejor le parezca, pero la idea general es que la EF ya sabe cómo traducir las cadenas a los miembros de propiedad.