C#Linq Nullable INT字段包含在List <int> SQL转换中

时间:2017-03-17 11:28:55

标签: c# sql linq

我有一张表格,其中包含需要管理员签名的表格列表,我想要做的是将表格列表过滤到他们可以签名的表格。

我得到他们经理的工作人员名单,然后将其列入员工名单。

var staffIds = manager.Staff.Select(x => x.Id).ToList();

然后我使用工作人员列表过滤表单列表。

我获取与经过身份验证的组织ID匹配的所有表单,然后删除已经被拒绝的任何表单,然后检查表单是否与以下某个表单匹配 -

该表格尚未首先签署&#34;提交表格的工作人员由经过身份验证的工作人员管理。

表单已经&#34;首先签署&#34;而不是&#34;第二次签署&#34;经过认证的工作人员经理是第一次签字的工作人员。

var forms = (from item in DbContext.Forms
            where item.OrganisationId == authenticatedOrganisationId
                  && item.RejectStaffId == null
                  && (( item.FirstSignOffStaffId == null && staffIds.Contains(item.StaffId))
                     || (item.FirstSignOffStaffId != null
                         && item.SecondSignOffStaffId == null
                         && staffIds.Contains(item.FirstSignOffStaffId.Value)))
                             select item).ToList();

问题是正在运行的SQL不正确。我期望SQL看起来像什么 -

SELECT *
FROM [Forms]
WHERE [OrganisationId] = 1
    AND [RejectStaffId] IS NULL
    AND (([FirstSignOffStaffId] IS NULL
        AND [StaffId] IN (1,2,3,4))
        OR ([FirstSignOffStaffId] IS NOT NULL
        AND [SecondSignOffStaffId] IS NULL
        AND [FirstSignOffStaffId] IN (1,2,3,4)))

但它运行

SELECT *
FROM [Forms] AS [item]
WHERE ([item].[OrganisationId] = 1) 
    AND [item].[RejectStaffId] IS NULL

然后剩下的就在内存中,这意味着返回所有表单(随着时间的推移将成为一个非常大的数据集)。

我发现,当我添加

时,它会中断
staffIds.Contains(item.FirstSignOffStaffId.Value)

字段&#34; FirstSignOffStaffId&#34;这是一个可以为空的INT,这似乎打破了与&#34; StaffId&#34;它很好,但这是一个INT字段。

有没有人知道如何使用可空的INT字段正确运行?

2 个答案:

答案 0 :(得分:2)

使用EF Core,这似乎是ContainsList <int?>本地执行的行为,请List <GUID?> <?php if (!defined('_PS_VERSION_')) exit; class MyCustomModule extends Module { public function __construct() { $this->name = 'mycustommodule'; /* This is the 'technic' name, this should equal to filename (mycustommodule.php) and the folder name */ $this->tab = 'module type category'; /* administration, front_office_features, etc */ $this->version = '1.0.0'; /* Your module version */ $this->author = 'Firstname Lastname'; /* I guess it was clear */ $this->need_instance = 0; /* If your module need an instance without installation */ $this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_); /* Your compatibility with prestashop(s) version */ $this->bootstrap = true; /* Since 1.6 the backoffice implements the twitter bootstrap */ parent::__construct(); /* I need to explain that? */ $this->displayName = $this->l('My module'); /* This is the name that merchant see */ $this->description = $this->l('Description of my module.'); /* A short description of functionality of this module */ $this->confirmUninstall = $this->l('Are you sure you want to uninstall?'); /* This is a popup message before the uninstalling of the module */ } } ?>

答案 1 :(得分:0)

使staffId成为一个nullables列表(以避免在查询表达式中输入类型)。像这样:

var staffIds = manager.Staff.Select(x => (int?)x.Id).ToList();

这就是为什么IQueryable是抽象的一个坏例子:你仍然必须知道很多关于底层提供者......