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

时间:2014-05-05 19:16:41

标签: vb.net linq entity-framework

面对感觉像是一个小挑战。我试图检索一个对象集合作为类型< ServicesViewModel>来自两种不同型号的型号<服务>和< BlacklistedServices>。

首先:输入<服务>,称之为服务。 (如第二个代码示例所示)

第二种:类型< BlacklistedServices>,称之为BlacklistedServices。

Dim BlacklistedServices As IQueryable(Of Models.BlacklistedServices ) = unitOfWork.AutoServiceBlackList.GetAll()

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

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

  1. 创建所有服务的集合,并且:
    1. 如果BlacklistedServices中存在服务记录,则设置相应的属性" Blacklisted"真实。
    2. 如果BlacklistedServices中存在服务记录,则确定相应的黑名单服务记录"强制"属性设置为并设置相应的属性"强制执行"无论价值如何。
  2. 我已经完成了大部分工作。我被困在部分(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()
    

    除了尝试在viewmodel上设置.Enforced属性外,它的工作正常。

    .Enforced = If(BlacklistedServices.Any(Function(BLS) BLS.ServiceName = service.Name),
              BlacklistedServices.FirstOrDefault(Function(BLS) BLS.ServiceName service.Name).Enforced, False)}).ToList()
    

    返回的错误如下:

      

    System.Data.EntityCommandCompliationException:{"发生错误   在准备命令定义时。查看内部异常   详细信息。"} InnerException:{"无法转换类型的对象   ' MySql.Data.Entity.SelectStatement'输入   ' MySql.Data.Entity.LiteralFragment'"}

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

    一如既往,感谢所有人的帮助!

3 个答案:

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

或者甚至

.Enforced = BlacklistedServices.Any(Function(BLS) BLS.ServiceName = service.Name) AndAlso BlacklistedServices.Where(Function(BLS) BLS.ServiceName service.Name).FirstOrDefault().Enforced

答案 1 :(得分:0)

尝试考虑声明可空 Enforced属性的中间(可能是匿名)类型。 所以你可以写:

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

答案 2 :(得分:0)

我遇到了同样的问题并更换了

.FirstOrDefault(y => y.value == rule);

通过

.Where(y => y.value == rule).FirstOrDefault();
根据Ealianis的评论。这解决了我的问题