How can I write custom comparison (definition for binary operator Equal) for entityframework object to an int?
I'm getting this error:
ex = {"The binary operator Equal is not defined for the types 'MySite.Domain.DomainModel.EntityFramework.NickName' and 'System.Int32'."}
What I tried to do was do a select all where the NickNameId = someIntPassedIn
... the problem is that the NickNameId is a foreign key, so when it compares the someIntPassedIn
to the NickNameId
it开发者_运维问答 pulls the whole NickName
object that the NickNameId
refers to and tries to compare the int to that object.
I need a solution here to allow it to compare the int to the NickName object's Id... so
A) How can I define the binary operator Equal for comparing these two objects
OR
B) How can I compare it directly to the id instead of the whole object?
You don't have to read this, but here's the SelectAllByKey method incase it helps:
(I passed in "NickNameId" and "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;
}
Let me know if you need any more info.
Thanks,
MattYou should call SelectAllByKey('NickName.ID','1')
.
Since ID
is property of property, you could use this extension method:
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;
}
The accepted answer seems way too complicated for the problem at hand, if I'm reading this correctly.
If I understand you correctly, you're trying to run a query like:
var q = from e in Context.SomeEntities
where e.NickNameId == someIntPassedIn
select e;
...but this won't work, because e.NickNameId
is an entity, not an integer.
To reference the Id
property, you can just refer to it, like this:
var q = from e in Context.SomeEntities
where e.NickNameId.Id == someIntPassedIn
select e;
Update: If you can't use strong-typed properties due to your level of abstraction (per your comment), then use query builder methods:
var q = (ObjectQuery<T>)Repository.SelectSomething();
return q.Where("it.NickName.Id = " + someIntPassedIn.ToString());
You can adapt this as you see fit, but the general point is that the EF already knows how to translate strings to property members.
精彩评论