Как я могу записать пользовательское сравнение (определение для бинарного оператора Equal) для объекта entityframework в int? - PullRequest
0 голосов
/ 21 декабря 2009

Я получаю эту ошибку:

ex = {"Бинарный оператор Equal не определен для типов 'MySite.Domain.DomainModel.EntityFramework.NickName' и 'System.Int32'."}

То, что я пытался сделать, это выбрать все, где NickNameId = someIntPassedIn ... проблема в том, что NickNameId является внешним ключом, поэтому, когда он сравнивает someIntPassedIn с NickNameId, он вытягивает NickName объект, на который NickNameId ссылается и пытается сравнить int с этим объектом.

Мне нужно здесь решение, чтобы оно могло сравнивать int с идентификатором объекта NickName ... так что

A) Как определить двоичный оператор Equal для сравнения этих двух объектов

OR

B) Как я могу сравнить его непосредственно с идентификатором вместо целого объекта?

Вам не нужно читать это, но вот метод SelectAllByKey, если он помогает:
(я передал "NickNameId" и "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;
    }

Дайте мне знать, если вам нужна дополнительная информация.

Спасибо,
Matt

Ответы [ 2 ]

2 голосов
/ 22 декабря 2009

Принятый ответ кажется способом слишком сложным для рассматриваемой проблемы, если я правильно читаю.

Если я вас правильно понимаю, вы пытаетесь выполнить запрос вроде:

var q = from e in Context.SomeEntities
        where e.NickNameId == someIntPassedIn
        select e;

... но это не сработает, потому что e.NickNameId является сущностью, а не целым числом.

Чтобы сослаться на свойство Id, вы можете просто обратиться к нему, например так:

var q = from e in Context.SomeEntities
        where e.NickNameId.Id == someIntPassedIn
        select e;

Обновление: Если вы не можете использовать свойства со строгим контролем типов из-за уровня абстракции (согласно вашему комментарию), тогда используйте методы построителя запросов :

var q = (ObjectQuery<T>)Repository.SelectSomething();
return q.Where("it.NickName.Id = " + someIntPassedIn.ToString());

Вы можете адаптировать это по своему усмотрению, но в целом EF уже знает, как переводить строки в члены свойства.

2 голосов
/ 21 декабря 2009

Вам следует позвонить SelectAllByKey('NickName.ID','1').

Поскольку ID является свойством свойства, вы можете использовать этот метод расширения:

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