【问题标题】:Linq to SQL nullable int?Linq to SQL 可以为空的int?
【发布时间】:2015-03-20 02:07:55
【问题描述】:

我有以下 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?),它作为参数传递到方法中。因此,当它为空时,查询不返回任何结果。但是如果我在 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 条记录。奇怪的是,如果我用“null”替换“folder.FolderID”(在 linq 代码中),它确实返回 6 条记录。因此,显然“null”和具有空值的对象之间存在差异。我只是不知道它是什么以及如何解决这个问题。

仅供参考,我的代码使 where 子句看起来像这样:

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

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

任何帮助将不胜感激。

【问题讨论】:

  • 执行该 linq 时 SQL Profiler 会显示什么?
  • 另外 - 您正在这里构造一个 linq 查询对象,但没有执行它(至少在您与我们共享的代码中)。
  • 我不熟悉 SQL Profiler。 db 对象是添加到我的项目中的 DataClasses1DataContext 对象。
  • db.log 的输出是“WHERE ([t0].[jobmst_type] @p0) AND ([t0].[jobmst_prntid] = @p1)”

标签: c# sql-server linq


【解决方案1】:

正如我在评论中已经提到的那样: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
{
    // ...
}

【讨论】:

    【解决方案2】:

    我认为当你有 null 时,你必须在表达式中添加 (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)
    

    【讨论】:

    • 该语法适用于连接语句中的可为空值。我的问题是 where 子句中的可为空值。我尝试了语法,但没有用。谢谢你。
    【解决方案3】:

    我最终为我的情况这样做了:

    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 设置为(动态)null 会禁用智能感知 b/c,一切都在运行时进行评估。所以,你的打字最好是准确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 2011-08-24
      • 1970-01-01
      相关资源
      最近更新 更多