2010-01-21 3 views
0

Я пытаюсь использовать AutoMapper и шаблон хранилища вместе с плавным интерфейсом и сталкивается с трудностями с проекцией Linq. Для чего это стоит, этот код отлично работает при простом использовании объектов в памяти. Однако при использовании поставщика базы данных он разбивается при построении графика запроса. Я пробовал использовать SubSonic и Linq для SQL с тем же результатом. Спасибо за ваши идеи.Есть ли способ использовать прогнозы Linq с методами расширения

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

public static IQueryable<MyUser> ByName(this IQueryable<MyUser> users, string firstName) 
{ 
    return from u in users 
      where u.FirstName == firstName 
      select u; 
} 

Вот код в памяти, который работает отлично

var userlist = new List<User> {new User{FirstName = "Test", LastName = "User"}}; 

Mapper.CreateMap<User, MyUser>(); 
var result = (from u in userlist 
        select Mapper.Map<User, MyUser>(u)) 
        .AsQueryable() 
        .ByName("Test"); 

foreach (var x in result) 
{ 
    Console.WriteLine(x.FirstName); 
} 

Это то же самое, что и при использовании SubSonic (или Linq to SQL или любого другого), который терпит неудачу. Это то, что я хотел бы сделать то работать с методами расширения ...

Mapper.CreateMap<User, MyUser>(); 

var result = from u in new DataClasses1DataContext().Users 
          select Mapper.Map<User, MyUser>(u); 

var final = result.ByName("Test"); 
foreach(var x in final) // Fails here when the query graph built. 
{ 
    Console.WriteLine(x.FirstName); 
} 

Цель здесь состоит, чтобы избежать необходимости вручную отобразить сгенерированный «Пользователь» объект в «MyUser» домен object- в другие слова, я пытаюсь найти способ использовать AutoMapper, так что я не такое отображение коды везде операции чтения базы данных необходимы:

var result = from u in new DataClasses1DataContext().Users 
          select new MyUser // Can this be avoided with AutoMapper AND extension methods? 
          { 
          FirstName = v.FirstName, 
          LastName = v.LastName 
          }; 

ответ

0

Ну я не знаю, LINQ-реализацию дозвуковой в , Однако причиной проблемы может быть то, что LINQ-Provider не сможет использовать вызов «Mapper». Он ожидает, что что-то, что может быть переведено в SQL.

Кстати, я бы использовал .ByName() в пользовательском запросе вместо текущей реализации. Поскольку в настоящее время результат должен отображаться для запуска .ByName(). Таким образом, вы извлекаете много экземпляров User из базы данных, затем их сопоставляете и фильтруете. Если вы будете использовать .ByName в «User», он может быть переведен на SQL, который никогда не должен быть восстановлен.

Так что я думаю это что-то, как это будет работать:

public static IQueryable<User> ByName(this IQueryable<User> users, 
             string firstName) 
{ 
    return from u in users 
     where u.FirstName == firstName 
     select u; 
} 

А теперь вы добавляете отображение часть до конца: Mapper.CreateMap();

var result = from u in new DataClasses1DataContext().Users.ByName("Test") 
       select Mapper.Map<User, MyUser>(u); 
// now the 'ByName'-constain can be ran on the database 

foreach(var x in result) 
{ 
    Console.WriteLine(x.FirstName); 
} 

Если он все еще не работает, вам может понадобиться, чтобы заставить использование LINQ к объекту для Mapper-части: Mapper.CreateMap();

var result = DataClasses1DataContext().Users.ByName("Test").ToList(); 
// now the result is a regualar list, so LINQ-to-object is used for the mapping part 

var final = from u in result 
        select Mapper.Map<User, MyUser>(u); 

foreach(var x in final) 
{ 
    Console.WriteLine(x.FirstName); 
} 

Кстати, вы могли бы хотеть добавить «SubSonic'-тег, так что дозвуковой эксперты ответить на ваш вопрос.

+0

Я подумал о том, что нужно сначала вызвать ToList, но я бы не хотел называть это до момента, когда код действительно должен перечислить данные. Другими словами, ваш средний фрагмент кода попадает в базу данных в вызове перечислителя в цикле foreach (что хорошо в этом случае). Ваш последний фрагмент попадает в базу данных при вызове ToList. Это не будет работать в моем случае, так как методы расширения не находятся в проекте базы данных ... случай IoC, это одна из двух реализованных реализаций базы данных. –

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