Comment puis-je écrire comparaison personnalisée (définition pour l'opérateur binaire égal) pour objet entityframework à un int?
Question
Je reçois cette erreur:
ex = { "L'opérateur binaire égal n'est pas défini pour les types de la MySite.Domain.DomainModel.EntityFramework.NickName 'et 'System.Int32'."}
Ce que j'ai essayé de faire était de sélectionner tous les NickNameId = someIntPassedIn
où le ... le problème est que la NickNameId est une clé étrangère, alors quand il compare le someIntPassedIn
au NickNameId
il tire tout l'objet de NickName
que le NickNameId
fait référence à et tente de le comparer int de cet objet.
Je ici besoin d'une solution pour lui permettre de comparer l'int Id de l'objet nickname ... donc
A) Comment puis-je définir l'opérateur binaire égal pour comparer ces deux objets
ou
B) Comment puis-je comparer directement à l'ID au lieu de l'objet entier?
Vous ne devez pas lire cela, mais voici la méthode SelectAllByKey Incase il aide:
(je suis passé dans « NickNameId » et « 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;
}
Faites-moi savoir si vous avez besoin de plus d'information.
Merci,
Matt
La solution
Vous devez appeler SelectAllByKey('NickName.ID','1')
.
Depuis ID
est la propriété de la propriété, vous pouvez utiliser cette méthode d'extension:
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;
}
Autres conseils
La réponse acceptée semble chemin trop compliqué pour le problème à portée de main, si je lis ceci correctement.
Si je vous comprends bien, vous essayez d'exécuter une requête comme:
var q = from e in Context.SomeEntities
where e.NickNameId == someIntPassedIn
select e;
... mais cela ne fonctionnera pas, parce que e.NickNameId
est une entité, pas un entier.
Pour faire référence à la propriété Id
, vous pouvez simplement s'y référer, comme ceci:
var q = from e in Context.SomeEntities
where e.NickNameId.Id == someIntPassedIn
select e;
Mise à jour: Si vous ne pouvez pas utiliser les propriétés fortement typé en raison de votre niveau d'abstraction (par votre commentaire), puis utilisez méthodes constructeur de requête :
var q = (ObjectQuery<T>)Repository.SelectSomething();
return q.Where("it.NickName.Id = " + someIntPassedIn.ToString());
Vous pouvez adapter cela comme bon vous semble, mais le point de vue général est que l'EF sait déjà comment traduire les chaînes aux membres de la propriété.