views:

190

answers:

2

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,
Matt

+1  A: 

You 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;
}
LukLed
You are a God! Thank you so much!
Matt
A: 

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.

Craig Stuntz
That's correct, except how am I supposed to know when it's an entity (when I'm supposed to use the 2nd one you provided) and when it's not? The thing is, I'm using a generic repository, so everything about it is way too complicated... Either way, his solution worked, just plug and play, so I can't complain.
Matt
See update for using strings instead of strong-typed references. I'm not saying that you shouldn't be happy that you have something that works; only that this is trivial to do in the EF.
Craig Stuntz