различия между int32.Equals Int? == int? для Linq - PullRequest
0 голосов
/ 04 марта 2012

Я знаю, что название не очень понятно, но здесь есть проблема. Я пытаюсь разработать простую веб-страницу с asp.net mvc, и у меня есть контроллер категории, и я пытаюсь объяснить ситуацию в приведенном ниже блоке кода.

    //
    // GET: /Category/
    public ViewResult Index(int? id)
    {

        if (id == null)
        {
            //Gives the following error if nut null, 1,2 etc
            //Unable to cast the type 'System.Nullable`1' to type 'System.Object'. 
            //LINQ to Entities only supports casting Entity Data Model primitive types.
            var categories = db.Categories.Where( c => Int32.Equals(c.ParentCategoryId, id));
            return View(categories);
        }
        else
        {
            //Does not show any category, must show item if ParentCategoryId is null
            var categories = db.Categories.Where(c => c.ParentCategoryId == id);
            return View(categories);
        }
    }

Мои данные

ID    Name            ParentId
----------------------------------
1   Computer    NULL
2   TV          NULL
3   Laptop          1
4   Desktop         1

Ответы [ 3 ]

1 голос
/ 04 марта 2012

При использовании Linq для чего-либо ответ зависит от реализации поставщика Linq и от того, как / если они решили обработать этот случай.

Когда вы пишете c => c.ParentCategoryId == id, это дерево выражений.Поставщик Linq разбивает это на (1) доступ к свойству (ParentCategoryId), (2) доступ к переменной (id) и (3) он связывает два операнда вместе сравнением равенства (==),Этот код на самом деле не работает как функция, он просто обрабатывается как выражение

Аналогично, c => Int32.Equals(c.ParentCategoryId, id) разбивается на вызов метода (Int32.Equals), который принимает два параметра.Поставщик Linq решил реализовать вызов на Int32.Equals так же, как и ==, тогда он должен быть идентичным.Тем не менее, более вероятно, что они не

Второй оператор Linq, вероятно, преобразуется в

select * from Categories where ParentCategoryId = NULL

, что никогда не было верно в ANSI SQL, поэтому вы каждый раз получаете 0 записей.Вам повезет, сказав .Where(x => x.ParentCategoryId != null) или .Where(x => x.ParentCategoryId.HasValue).Опять же, это зависит от того, что выбрали создатели провайдера Linq, но один из них обязательно будет работать так, как вы ожидаете.

1 голос
/ 04 марта 2012
    public ViewResult Index(int? id = 0)
    {
        var categories = db.Categories
            .Where(c => (c.ParentId.HasValue ? c.ParentId : 0) == id)
                 .ToList();
        return View(categories);
    }
0 голосов
/ 04 марта 2012

Попробуйте этот код:

    if (id == null)
    {
      var categories = db.Categories.Where( c => !c.ParentCategoryId.HasValue); 
      ..             
    }
...