实体框架选择带逻辑的语句

Sea*_*bbs 1 linq vb.net entity-framework

面对什么感觉是一个小挑战.我试图从两个不同的<Services>和<BlacklistedServices>模型中检索一个对象集合作为<ServicesViewModel>类型.

第一种:键入<Services>,将其命名为Services.(显示在第二个代码示例中)

第二种:键入<BlacklistedServices>,将其命名为BlacklistedServices.

Dim BlacklistedServices As IQueryable(Of Models.BlacklistedServices ) = unitOfWork.AutoServiceBlackList.GetAll()
Run Code Online (Sandbox Code Playgroud)

这两个集合之间的关系如下.列入黑名单的某些服务作为BlacklistedServices中的记录存在.

以下是我想要实现的目标:

  1. 创建所有服务的集合,并:
    1. 如果BlacklistedServices中存在服务记录,则将相应的属性"Blacklisted"设置为True.
    2. 如果BlacklistedServices中存在服务记录,则确定相应的黑名单服务记录的"强制"属性设置为什么,并将相应的属性"强制"设置为该值.

我已经完成了大部分工作.我被困在部分(1.2).

以下是我的工作代码:

    Services= uow.Services.GetAll().Select(Function(service) New ServiceViewModel() With
    {.ServiceID = service.ServiceID,
    .PropertyABC= service.ABC,
    .PropertyDEF= service.DEF.
    .Blacklisted = BlacklistedServices.Any(Function(BLS) BLS.ServiceName = service.Name),
    .Enforced = If(BlacklistedServices.Any(Function(BLS) BLS.ServiceName = service.Name),
          BlacklistedServices.FirstOrDefault(Function(BLS) BLS.ServiceName service.Name).Enforced, False)}).ToList()
Run Code Online (Sandbox Code Playgroud)

除了尝试在viewmodel上设置.Enforced属性时,它的工作方式非常完美.

.Enforced = If(BlacklistedServices.Any(Function(BLS) BLS.ServiceName = service.Name),
          BlacklistedServices.FirstOrDefault(Function(BLS) BLS.ServiceName service.Name).Enforced, False)}).ToList()
Run Code Online (Sandbox Code Playgroud)

返回的错误如下:

System.Data.EntityCommandCompliationException:{"准备命令定义时发生错误.有关详细信息,请参阅内部异常."} InnerException:{"无法将类型为'MySql.Data.Entity.SelectStatement'的对象强制转换为'MySql. Data.Entity.LiteralFragment"."}

问题似乎是在尝试使用逻辑时(If).在大多数情况下,我不认为这在构造新对象和确定作为参数传递的内容时会是一个问题; 但是,这或多或少被转换为必须发送到服务器的IQueryable表达式树.那么实体框架可能无法将逻辑转换为SQL逻辑?

一如既往,任何和所有的帮助表示赞赏!

MHo*_*lis 5

我一直在使用MySQL的.Net连接器和EF,并且遇到了几种奇怪的情况,其中非常相似的LINQ语句工作,而其他人没有.特别是当涉及到其他lambda表达式中的FirstOrDefault时.也许尝试

.Enforced = If(BlacklistedServices.Any(Function(BLS) BLS.ServiceName = service.Name),
          BlacklistedServices.Where(Function(BLS) BLS.ServiceName service.Name).FirstOrDefault().Enforced, False)
Run Code Online (Sandbox Code Playgroud)

或者甚至是

.Enforced = BlacklistedServices.Any(Function(BLS) BLS.ServiceName = service.Name) AndAlso BlacklistedServices.Where(Function(BLS) BLS.ServiceName service.Name).FirstOrDefault().Enforced
Run Code Online (Sandbox Code Playgroud)

  • 添加.Where(<Expression>).FirstOrDefault()有效!现在,如果我们只知道为什么?大声笑. (2认同)