开发者

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,

Matt


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;
}


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜