Orderby слева присоединяется к нулевому значению - PullRequest
0 голосов
/ 08 октября 2019

Следующая ситуация:

  • Таблица пользователей
  • Таблица адресов
  • Пользователь имеет одну необязательную ссылку на таблицу адресов(= объединение влево)

Запрос для извлечения данных:

IQueryable<User> query = 
    from u in _dbContext.Users
        join a in _dbContext.Address on u.AddressId equals a.Id into address
        from addresses in address.DefaultIfEmpty()
    select new User(u, a); 

Теперь я хочу выполнить сортировку по запросу на основе муниципалитета с адресом

query = query.OrderBy(u => u.Address.Municipality);

Проблема в том, что адрес может иметь нулевое значение (поскольку адрес является необязательным), и по этой причине он выдает следующее исключение.

NullReferenceException: Object reference not set to an instance of an object.

Есть ли способ заказатьна муниципалитете, зная, что это может быть нулевым?

Уже пробовал следующие вещи с тем же результатом:

query = query.OrderBy(u => u.Address.Municipality ?? "");
query = query.OrderBy(u => u.Address == null).ThenBy(u => u.Address.Municipality);

Ответы [ 3 ]

0 голосов
/ 08 октября 2019

Вы можете написать свой компаратор так:

        public class One
        {
            public int A { get; set; }
        }

        public class Two
        {
            public string S { get; set; }
        }

        public class T
        {
            public One One { get; set; }
            public Two Two { get; set; }
        }

        public class OrderComparer : IComparer<Two>
        {
            public int Compare(Two x, Two y)
            {
                if (((x == null) || (x.S == null)) && ((y == null) || (y.S == null)))
                    return 0;

                if ((x == null) || (x.S == null))
                    return -1;

                if ((y == null) || (y.S == null))
                    return 1;

                return x.S.CompareTo(y.S);
            }
        }

        static void Main(string[] args)
        {
            var collection = new List<T> {
                new T{ One = new One{A=1}, Two = new Two{ S="dd" } },
                new T{ One = new One{A=5}, Two = null },
                new T{ One = new One{A=0}, Two = new Two{ S=null } },
                new T{ One = new One{A=6}, Two = new Two{ S="aa" } },
            };

            var comparer = new OrderComparer();

            collection = collection.OrderBy(e => e.Two, comparer).ToList();
        }

Но в вашем случае вы должны написать var collection = query.AsEnumerable().OrderBy(x=>x.Address).

Также есть другой метод:

var result = query.Where(x=>x.Address==null || x.Address.Municipality==null)
.Union(query.Where(x.Address!=null && x.Address.Municipality!=null).OrderBy(x=>x.Address.Municipality));
0 голосов
/ 09 октября 2019

Я создаю простую демонстрацию, и она хорошо работает, когда я добавляю обнуляемый внешний ключ к двум таблицам.

Кроме того, я не понимаю, что такое select new User(u, a); в вашем коде.

Ниже приведен пример кода:

Модели:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ForeignKey("Address")]
    public int? AddressId { get; set; }

    public Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public string AddressName { get; set; }
    public string Municipality { get; set; }
}

Действие:

IQueryable<User> query =
        from u in _context.Users
        join a in _context.Address on u.AddressId equals a.Id into address
        from addresses in address.DefaultIfEmpty()
        select new User
        { 
            Id = u.Id,
            Name = u.Name,
            AddressId = u.AddressId,
            Address = addresses
        };

query = query.OrderBy(u => u.Address.Municipality);
0 голосов
/ 08 октября 2019

Вы можете использовать query = query.OrderBy(u => u.Address.Municipality.HasValue);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...