2015-06-10 2 views
0

Есть ли способ сделать это динамически динамически, поэтому мне не нужно повторять себя?динамический linq для сущностей, соответствующих DRY

var result = from c in _Entities.Cars 
where c.Colour == "White" 
select c; 

var result = from m in _Entities.Bikes 
where m.Colour == "White" 
select m; 

etc... 

как в:

var entities = new List<string> {"Cars", "Bikes"}; 
foreach (var e in entities) 
{ 
    var result = from m in e //pseudo code 
    where m.Colour == "White" 
    select m; 
} 

ответ

4

Если Автомобили и велосипеды реализовать общий интерфейс, скажем IVehicle, который имеет свойство Color, можно определить функцию:

public IEnumerable<IVehicle> GetWhiteVehicles(IEnumerable<IVehicle> vehicles) { 
    return vehicles.Where(p => p.Colour == "White"); 
} 

и затем

var result = GetWhiteVehicles(_Entities.Cars); 
var result = GetWhiteVehicles(_Entities.Bikes); 

Если автомобили и Велосипеды создаются классы с Entity Framework, вы можете все-таки сделать их реализовать интерфейс, добавив новый файл с частичным определением классов с таким же названием:

public partial class Bikes : IVehicle { } 
public partial class Cars : IVehicle { } 
+0

Да, но мне нужен тип возврата из GetWhiteVehicles, который будет List , Lis и т. Д. – user441365

+0

Они такого типа, это не просто указано. Просто определите переменные явно: List result = GetWhiteVehicles (_Entities.Cars) .ToList(); или добавить ToList() внутри функции – LInsoDeTeh

+0

еще одна вещь. мои классы действительно генерируются из Entity Framework. Что вы имеете в виду с добавлением нового исходного файла? – user441365

0

Это должно работать:

var entities = new List<List<dynamic>> {_Entities.Cars.ToList<dynamic>(), _Entitites.Bikes.ToList<dynamic>()}; 
foreach (var l in entities) 
{ 
    var result = from m in l 
     where m.Colour == "White" 
     select m; 
} 

Таким образом, вы избегаете любых изменений в своем бизнес-модуле. Однако, следовательно, тип dynamic разрешен только во время выполнения, нет способа гарантировать, что свойство Colour действительно существует в этом типе.

+0

это не работает – user441365

+0

@ user441365 Теперь он должен – HimBromBeere

+0

Я бы избегал использовать отражение, когда это не нужно. –

0

Добавить интерфейс, содержащий цвет (IColorful). Установите свои автомобили и велосипеды, чтобы реализовать этот интерфейс. Марка и вызвать функцию:

List<IColorful> FindByColor(IEnumerable<IColorful> list, string color) 
{ 
    List<IColorful> result = list.Where(item => item.Color == color).ToList(); 
    return result; 
} 

Вызов его следующим образом:

var entities = FindByColor(_Entities.Cars, color); 
entities.AddRange(FindByColor(_Entities.Bikes, color)) 
+0

Зачем это делать в памяти, а не в базе данных? –

0

Сначала либо определить базовый класс, они оба получают из, или они оба интерфейса реализации. Я собираюсь предположить, что здесь реализуется интерфейс IColoured с свойством Colour. (Хотя я буду замечать, что в именах участников обычно используется en-US, поэтому цвета представлены свойством Color).

Так, что ваш класс автомобилей был создан EF как:

namespace SomeNamespace 
{ 
    public partial class Cars 
    { 
    /*…*/ 
    public string Colour { get; set; } 
    /*…*/ 
    } 
} 

Тогда вы можете иметь файл с:

namespace SomeNamespace 
{ 
    public partial class Cars : IColoured 
    { 
    } 
} 

Поскольку два partial части кода объединены в составлении определение класса вашего кода просто необходимо указать, что интерфейс реализован, тот факт, что свойство соответствия находится в другом файле, не имеет значения.

Тогда:

public static IQueryable<T> FilterByColour<T>(this IQueryable<T> source, string colour) 
    where T : IColoured 
{ 
    return source.Where(p => p.Colour == colour); 
} 

Теперь вы можете использовать _Entities.Cars.FilterByColour("white"), _Entities.Bikes.FilterByColour("blue") и т.д.Если фильтрация по "white" был особенно распространен случай, то либо:

Важно: Никогда не определяют такой метод, принимая IEnumerable<>, если у вас нет уважительной причины для (например, используя что-то, что не совместимо с EF), используйте IQueryable<>, так что он все еще обрабатывается EF и может быть отфильтрован по базе данных, а не иметь все извлеченное из базы данных и отфильтрованное в вашем приложении.

public static IQueryable<T> FilterWhite<T>(this IQueryable<T> source) 
    where T : IColoured 
{ 
    return source.FilterByColour("white"); 
} 

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

public static IQueryable<T> FilterWhite<T>(this IQueryable<T> source) 
    where T : IColoured 
{ 
    return source.Where(p => p.Colour == "white"); 
} 

будет работать.

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