Как обойти свойства NotMapped в запросах?

У меня есть метод, который выглядит так:

    private static IEnumerable<OrganizationViewModel> GetOrganizations()
    {
        var db = new GroveDbContext();

        var results = db.Organizations.Select(org => new OrganizationViewModel
        {
            Id = org.OrgID,
            Name = org.OrgName,
            SiteCount = org.Sites.Count(),
            DbSecureFileCount = 0,
            DbFileCount = 0
        });

        return results;
    }

Это возвращает результаты довольно быстро.

Однако вы заметите, что у OrganizationViewModel есть свойства, для которых установлено значение «0». В модели Organization есть свойства, которые я добавил через разделяемый класс и украсил [NotMapped]: UnsecureFileCount и SecureFileCount.

Если я изменю эти 0 на что-то полезное...

   DbSecureFileCount = org.SecureFileCount,
   DbFileCount = org.UnsecureFileCount

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

Однако, поскольку EF не прислушивается к моим аргументам, я попробовал другой подход:

    private static IEnumerable<OrganizationViewModel> GetOrganizations()
    {
        var db = new GroveDbContext();

        var results = new List<OrganizationViewModel>();
        foreach (var org in db.Organizations)
        {
            results.Add(new OrganizationViewModel
            {
                Id = org.OrgID,
                Name = org.OrgName,
                DbSecureFileCount = org.SecureFileCount,
                DbFileCount = org.UnsecureFileCount,
                SiteCount = org.Sites.Count()
            });
        }

        return results;
    }

Технически это дает мне правильные результаты без исключения, но это занимает вечность. (Под «навсегда» я подразумеваю более 60 секунд, тогда как первая версия дает результаты менее чем за секунду.)

Есть ли способ оптимизировать второй подход? Или есть способ заставить работать первый подход?


person Sailing Judo    schedule 15.11.2012    source источник
comment
Второй метод займет больше времени, потому что он будет переносить ваши организации в память, а не позволять вашей базе данных обрабатывать запрос. Я тоже сталкивался с этой проблемой в прошлом, и, боюсь, я тоже не нашел для нее решения.   -  person jtiger    schedule 16.11.2012


Ответы (2)


Другой вариант - загрузить значения обратно как анонимный тип и пройтись по ним, чтобы загрузить вашу модель представления (n + 1, скорее всего, является причиной медлительности).

Например:

var results = db.Organizations.Select(org => new
        {
            Id = org.OrgID,
            Name = org.OrgName,
            DbSecureFileCount = org.SecureFileCount,
            DbFileCount = org.UnsecureFileCount,
            SiteCount = org.Sites.Count()
        }).ToList();

var viewmodels = results.Select( x=> new OrganizationViewModel
{
    Id = x.Id,
        Name = x.Name,
        DbSecureFileCount = x.DbSecureFileCount,
        DbFileCount = x.DbFileCount,
        SiteCount = x.SiteCount
});

Извините за форматирование; Я печатаю на телефоне.

person ilivewithian    schedule 15.11.2012
comment
Это ничего не меняет. Этот акт наличия двух дополнительных несопоставленных свойств в .Select вызывает ошибку, а не модель представления. Я попробовал то, что вы сказали, и это действительно вызвало исключение. - person Sailing Judo; 16.11.2012

Вы в основном лениво загружаете каждый объект на каждой итерации цикла, вызывая n+1 запросов.

Что вам нужно сделать, так это перенести всю коллекцию в память и использовать ее оттуда.

Образец кода:

var organizationList = db.Organizations.Load();
foreach (var org in organizationList.Local)
    {
       //Here you are free to do whatever you want
    }
person yoel halb    schedule 21.11.2013