2016-08-09 2 views
1

У меня есть простая модель просмотра, которая заполняется, но проблема в том, что веб-страница содержит множество списков выбора и для каждого списка выбора. Я вызываю процедуру базы данных для получения данных. список.Параллельные вызовы базы данных SQL Server из модели просмотра

Возможно ли, для выполнения, выполнять вызовы базы данных асинхронно или параллельно?

У меня есть такой код:

// controller 
public ActionResult Index() 
{ 
    model = new SampleViewModel();  
    model.Populate(database); 
    return View(model); 
} 

// view model 
public class SampleViewModel 
{ 
    public SampleViewModel(DbContext db) 
    { 
     _list1 = context.Db.SqlQuery<SelectList1>("SELECT Id, Value FROM dbo.Table1").ToList(); 
     _list2 = context.Db.SqlQuery<SelectList2>("SELECT Id, Value FROM dbo.Table2").ToList(); 
     _list3 = context.Db.SqlQuery<SelectList3>("SELECT Id, Value FROM dbo.Table3").ToList(); 
     _list4 = context.Db.SqlQuery<SelectList4>("SELECT Id, Value FROM dbo.Table4").ToList(); 
     _list5 = context.Db.SqlQuery<SelectList5>("SELECT Id, Value FROM dbo.Table5").ToList(); 
    } 

    private readonly List<SelectList1> _list1; 
     public int SelectedList1Id { get; set; } 
     public IEnumerable<SelectListItem> List1 { get { return new SelectList(_list1, "Id", "Value");} } 

    -//- _list2 
    -//- _list3 
    -//- _list4 
    -//- _list5 
} 

Как вы можете видеть, _list3 ждет _list2 и _list2 ждет _list1 и это может медленный запросу много. Причина, по которой модель представления заполняется, заключается в том, что в реальном сценарии эти списки выбора связаны друг с другом, а модель содержит информацию о выбранных идентификаторах, и с этими идентификаторами я могу перестроить списки выбора, например, если проверка модели не удалась.

Любая идея? Могу ли я использовать какой-то подход асинхронного ожидания и поможет ли он мне в этом случае против SQL Server 2008?

+0

(psst, это Model View Controller - это не «модель взгляда», это модель) – Will

ответ

1

Вы можете использовать параллельные библиотеки задач Paralle.Invoke метод для выполнения многих задач параллельно.

Parallel.Invoke(() =>{ 
    // Execute some code here  
},() => 
{ 
    // Execute some other code here 
}); 

Лично я не передаю конкретный объект DbContext моей модели. Просмотр моделей должен быть простым POCO. Он не должен иметь никаких знаний о вашей технологии доступа к данным. Поэтому мое личное предпочтение заключается в сохранении кода доступа к данным отдельно от моей модели представления. Поэтому я никогда не читал значения из базы данных в конструкторе модели представления с конкретным объектом, как вы.

Предполагая, что вы просто ПОКО вид модели, как этот

public class CreateViewModel 
{ 
    public List<SelectListItem> States {set;get;} 
    public List<SelectListItem> UserTypes {set;get;} 
} 

В вашем GET действии, вы можете использовать Parallel.Invoke для загрузки свойств данных на 2.

var vm = new CreateViewModel(); 
Parallel.Invoke(() =>{ 
    vm.States = db.States.Select(s=>new SelectListItem { Value=s.Id.ToString(), 
                 Text=s.Name }).ToList(); 
},() => 
{ 
    vm.UserTypes= db.UserTypes.Select(s=>new SelectListItem { Value=s.Id.ToString(), 
                   Text=s.Name }).ToList(); 
}); 
return View(vm); 

Кэширование

Если они часто обращались пункты для вашего выпадающего списка, я предлагаю вам кэшировать эти данные вместо запроса таблицы БД каждый раз. Вы можете использовать значение по умолчанию MemoryCache.

+0

спасибо, я попробую! :-) Причина, по которой я населяю модель представления, заключается в том, что я не хочу иметь контроллер жира или добавить еще один уровень обслуживания, я еще не настолько опытен, поэтому, возможно, в следующем проекте я попробую несколько разных aproach – Muflix

+0

и я не хочу использовать кеш, потому что эта проблема для бэкэнда для администраторов, но идея, которую он вызывает, - отслеживать последнее время обновления таблицы базы данных, а если она изменяется, сбросить кеш .. я тоже буду думать об этом – Muflix

Смежные вопросы