动态linq实体符合DRY

时间:2015-06-10 09:16:50

标签: c# asp.net linq linq-to-entities

有没有办法动态地执行以下操作,所以我不必重复自己?

'e'

如:

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...

4 个答案:

答案 0 :(得分:4)

如果汽车和自行车实现了一个通用界面,比如具有Color属性的IVehicle,你可以定义一个函数:

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

然后

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

如果汽车和自行车是从实体框架生成的类,您可以通过添加一个新的源文件来实现一个接口,该文件具有相同名称的类的部分定义:

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

答案 1 :(得分: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;
}

因此,您可以避免对business-modell进行任何更改。但是因此dynamic - 类型仅在运行时解析,因此无法确保属性Colour确实存在于该类型上。

答案 2 :(得分: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))

答案 3 :(得分: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"过滤是一种特别常见的情况,那么:

重要提示:如果您没有充分理由(例如使用与EF不兼容的内容),请不要将此方法定义为使用IEnumerable<>,使用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");
}

会工作。