2010-08-24 3 views
0

Я уверен, что я пытаюсь сделать это довольно просто, но я боюсь. Я просто хочу проецировать IQueryable в пару ключевых значений.Project generic type в KeyValuePair

Это часть моего класса:

public DropDownListActionResult(IQueryable<T> dataItems, Func<T, int> keySelector, Func<T, string> valueSelector, int? selectedID) 
{ 
    _dataItems = dataItems; 
    _keySelector = keySelector; 
    _valueSelector = valueSelector; 
    _selectedID = selectedID; 
} 

public ActionResult Result() 
{ 
    var items = _dataItems.Select(item => 
       new KeyValuePair<int, string>(_keySelector.Invoke(item), _valueSelector.Invoke(item))) 
       .OrderBy("Value") 
       .ToList(); 
    items.Insert(0, new KeyValuePair<int, string>(0, "")); 

    var list = new SelectList(items, "Key", "Value", _selectedID); 

    return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; 
} 

И я призываю его, как так из модульного тестирования.

var _stubRepository = MockRepository.GenerateStub<IGalleryRepository>(); 
    _stubRepository.Stub(x => x.Mediums).Return((
     new[] { 
     new Medium { MediumID = 1, MediumDescription = "Medium A"}, 
     new Medium { MediumID = 2, MediumDescription = "Medium B"}, 
    }).AsQueryable()); 

    _controller = new MediumController(_stubRepository, null, null); 

    var z = _controller.PopulateDropDownList(-1) as DropDownListActionResult<Medium>; 
    var result = z.Result(); 
    Assert.IsInstanceOf<JsonResult>(result); 

Это метод PopulateDropDownList

public ActionResult PopulateDropDownList(int? ID) 
{ 
    return new DropDownListActionResult<Medium>(_repository.Mediums, 
               x => x.MediumID, 
               x => x.MediumDescription, ID); 
} 

При запуске модульного теста не проходит никаких проблем. Но когда я исполню против LINQ к SQL, я получаю ошибку:

Method 'Int32 Invoke(L2S_DomainModel.Entities.Medium)' has no supported translation to SQL.

+0

Именно то, что говорится в сообщении об ошибке. Генератор LinqToSql не знает, как преобразовать произвольные лямбды (_keySelector.Invoke) в фактический SQL. Будет работать с перечислимым, но не запрашиваемым. Рассмотрите возможность обертывания лямбда с помощью выражения <>. –

+0

Я уже пробовал использовать выражения, но, похоже, никуда не денусь. Однако с небольшим усилием мне удалось заставить все работать. Смотри ниже. –

ответ

0
public DropDownListActionResult(IQueryable<T> dataItems, Expression<Func<T, int>> keySelector, Expression<Func<T, string>> valueSelector, int? selectedID) 
{ 
    _dataItems = dataItems; 
    _keySelector = keySelector; 
    _valueSelector = valueSelector; 
    _selectedID = selectedID; 
} 

public ActionResult Result() 
{  
    var items = _dataItems.Select(item => 
       new KeyValuePair<int, string>(_keySelector.Compile().Invoke(item), _valueSelector.Compile().Invoke(item))) 
       .ToDictionary(item => item.Key, item => item.Value); 

    items.Add(0, ""); 

    var list = new SelectList(items.OrderBy(i => i.Value), "Key", "Value", _selectedID); 

    return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet };  
}