如何在子查询中将sql转换为linq

时间:2018-10-30 06:12:20

标签: linq linq-to-sql subquery

select * 
from Vehicletab 
where LicencePlate not in (select LicencePlate 
                           from AssignVechiletab 
                           where IsAssign = 'true' 
                             and CreatedDate = '2018-10-29') 
  and VendorID = 1153

2 个答案:

答案 0 :(得分:0)

您的内部选择独立于前一个。所以你可以做到

var innerList = AssignVechiletab.Where(a => a.IsAssign && a.CreatedDate == "2018-10-29");
var mainList = Vehicletab.Where(v => !innerList.Contains(v.LicencePlate) && v.VendorID == 1153);

我不知道LicencePlate的类型,所以我使用了Contains方法。您可以使用relevent方法,例如IndexOf,...

答案 1 :(得分:0)

您真遗憾忘记给我们查询的要求!我必须从您的SQL语句中猜测您真正想要的是什么。

在我看来,您有一个AssignVehicleTabs序列。每个AssignVehicleTab至少具有属性LicensePlateIsAssignCreatedDate

此外,您还有一个VehicleTabs序列,其中每个VehicleTab都有一个LicensePlate

您可以进行查询,结果是LicensePlates中所有AssignVehicleTabsIsAssign中的CreatedDate等于2018-10-29:

DateTime myDate = new DateTime (2018, 10, 29);
var assignedLicensePlatesOnMyDate = myDbContext.AssignVehicleTabs
    .Where(assignVehicleTabe => assignVehicleTab.IsAssign
                             && assignVehicleTabe.CreatedDate == myDate)
    .Select(assignVehicleTab => assignVehicleTab.LicensePlate);

用词表示:从所有AssignVehicleTabs的序列中,仅保留在AssignVehicleTabs上分配并创建的myDate。从其余的AssignVehicleTab中仅获得LicensePlate

注意:结果为IQueryable<..>:查询已创建,但尚未执行。不需要与数据库进行通信。

  

在lambda表达式中使用适当的标识符会使它们   更容易阅读。建议:将单数名词用于那些   代表一个收集项目,对对象使用复数名词   代表集合。

现在,从VehicleTabs的集合中,您只需要具有VehicleTabs序列中的车牌的assignedLicensePlatesOnMyDate

为此,您使用Queryable.Contains

var result = myDbContext.VehicleTabs
    .Where(vehicleTab => assignedLicensePlatesOnMyDate.Contains(vehicleTab.LicensePlate));

换句话说:从VehicleTabs的集合中,仅保留VehicleTabs中具有LicensePlate的{​​{1}}。

请注意,查询仍未执行。只有不返回assignedLicensePlatesOnMyDate的LINQ函数才会执行查询。考虑一下IQueryable<...>ToList()FirstOrDefault()Any()等。在内部,他们将呼叫Count()和/或较低级别的foreach和{{ 1}},它将执行查询。

由您决定是否要将其放入一个大型LINQ查询中。这不会提高处理速度。它肯定会降低可读性,从而降低可测试性和可维护性。