Linq to SQL nullable int?

时间:2015-02-25 22:28:35

标签: c# sql-server linq

我有以下linq查询(非常简单):

var jobs = from j in db.jobmsts
    join jd in db.jobdtls on j.jobdtl_id equals jd.jobdtl_id
    where j.jobmst_type != 1 && j.jobmst_prntid.Equals(folder.FolderID)
    orderby j.jobmst_name
    select new
        {
            JobID = j.jobmst_id,
            JobName = j.jobmst_name,
            Description = j.jobmst_desc,
            Source = jd.Source
        };

folder.FolderID是一个可以为空的int(int?),它作为参数传递给方法。因此,当它为null时,查询不返回任何结果。但是如果我在TSQL中执行相同的查询:

select * from jobmst j 
join jobdtl jd on j.jobdtl_id = jd.jobdtl_id 
where j.jobmst_type != 1 and j.jobmst_prntid is null

我得到6条记录。奇怪的是,如果我替换" folder.FolderID"用" null" (在linq代码中),它确实返回6条记录。所以,显然" null"之间存在差异。和一个空值的对象。我只是不知道它是什么以及如何解决这个问题。

仅供参考,我有代码,以便where子句看起来像这样:

where j.jobmst_type != 1 && j.jobmst_prntid == folder.FolderID

但它也没有产生任何结果。

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:3)

正如我在评论中已提到的那样:Compare nullable types in Linq to Sql

这个问题的答案也适用于此:Linq to SQL在查询可空类型时表现得有些奇怪。如果可空类型的值为null,则解决方案是显式检查null。如果您不想编写两个查询,只需编写不同的where子句(您必须混合使用一些lambda语法):

Expression<Func<Job,bool>> predicate;
if(folder.FolderID == null) {
    predicate = j=>j.jobmst_prntid == null && j.jobmst_type != 1;
} else {
    predicate = j=>j.jobmst_prntid == folder.FolderID && j.jobmst_type != 1;
}

//...
.Where(predicate)
select new
{
    // ...
}

答案 1 :(得分:2)

我认为当你有空

时,你必须在表达式中添加(int ?)
j.jobmst_prntid.Equals ( folder.FolderID )
j.jobmst_prntid.Equals ( (int ? ) folder.FolderID )

更多参考: https://msdn.microsoft.com/en-us/library/bb882535.aspx

或者你可以试试这个

 where j.jobmst_type != 1 && j.jobmst_prntid.Equals(folder.FolderID== null ?   null : folder.FolderID)

答案 2 :(得分:0)

我最终为我的情况做了这件事:

List<Job> folderJobs = new List<Job>();
var tidalJobs = (dynamic) null;
if (folder.FolderID == 0)
{
    tidalJobs = from 
                    master in tidal.jobmsts
                join
                    detail in tidal.jobdtls
                on
                    master.jobdtl_id equals detail.jobdtl_id
                where 
                    master.jobmst_prntid.HasValue == false && master.jobmst_type != 1
                select new
                {
                    JobID = master.jobmst_id,
                    JobName = master.jobmst_name,
                    Description = master.jobmst_desc == null ? string.Empty : master.jobmst_desc,
                    Source = detail.jobdtl_cmd == null ? string.Empty : detail.jobdtl_cmd
                };
}
else
{
    tidalJobs = from
                    master in tidal.jobmsts
                join
                    detail in tidal.jobdtls
                on
                    master.jobdtl_id equals detail.jobdtl_id
                where 
                    master.jobmst_prntid == folder.FolderID && master.jobmst_type != 1
                select new
                {
                    JobID = master.jobmst_id,
                    JobName = master.jobmst_name,
                    Description = master.jobmst_desc == null ? string.Empty : master.jobmst_desc,
                    Source = detail.jobdtl_cmd == null ? string.Empty : detail.jobdtl_cmd
                };
}

foreach (var folderJob in tidalJobs)
{
    ...
}

简而言之,var tidalJobs =(dynamic)null和.HasValue == false是我需要的工作。唯一需要注意的是,将var设置为(dynamic)null会禁用intellisense b / c,所有内容都会在运行时进行评估。所以,你的打字最好是现场。