3

我有一个表tblOvrdImpVolsType,其中包含两个可以为空的外键列。当该行中的一个外键列为空时,我无法使用 Linq-To-SQL 删除该表中的一行。这是我的代码:

using (Databases.Global db = new Databases.Global())
{
    db.Log = Console.Out;
    var records = from iv in db.tblOvrdImpVolsType
                    join sm in db.tblSecurityMasterType 
                       on iv.FkSecurity equals sm.PkSecurity
                    where sm.Name == name
                    select iv; //returns only 1 record

    db.tblOvrdImpVolsType.DeleteAllOnSubmit<MyTableType>(records);

    int numDeletes = db.GetChangeSet().Deletes.Count; // = 1
    db.SubmitChanges(); //deletes 0 records
}
  • Databases.Global 继承自 DataContext 并具有我使用的表。

  • tblOvrdImpVolsType 有两个可为空的外键列(key1 和 key2)

  • 我感兴趣的行有这些键值(key1 = 9898,key2 = null)

  • 在我的 C# 代码中,key1 和 key2 的数据类型都是int?CanBeNull = true

  • 显示GetChangeSet()一条记录将被删除,但是当我检查数据库时,该行显然没有被删除。

  • 不抛出异常。

这是 DataContext 生成的 SQL:

DELETE FROM [tblOvrdImpVols] WHERE ([key1] = @p0) AND ([key2] = @p1)
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [9898]
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [Null]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.17929

我认为问题在于[key2] = @p1部分。因为我感兴趣的 key2 值为 null,所以 SQL 不好。下面的这些 SQL 查询说明了这一点。唯一的区别是条件中的isvs.:=key2

select * FROM [tblOvrdImpVols] WHERE ([key1] = 9898) AND ([key2] is null)
    --returns 1 row

select * FROM [tblOvrdImpVols] WHERE ([key1] = 9898) AND ([key2] = null)
    --returns 0 rows

我究竟做错了什么?我假设如果我可以让 DataContext 对象替换=is空值,则删除将起作用。我不知道该怎么做。我也假设这个问题以前被问过,但我找不到。

编辑:我最初将我的键称为“主键”而不是“外键”。我的意思是说“外国”。我编辑了我的帖子,改为说“外国”。我仍然有同样的问题。

4

2 回答 2

0

为确保您也捕获空值,您可以将查询修改为如下所示:

select * FROM [tblOvrdImpVols] 
WHERE ([key1] = @p0) AND 
([key2] = @p1 OR 
    ([key2] is null and @p1 is null) )
于 2013-07-16T17:07:13.757 回答
0

这里的主要问题 - 在 SQL 中,没有什么等于 NULL。NULL 甚至不等于它自己!"NULL = NULL" 在 SQL 查询中将评估为 "false"。因此,当您需要删除 [key2] == null 的行时,您需要编写 LINQ 查询,该查询将生成类似 SQL

“哪里 [key2] = @p1 AND [key2] 为空”

代替

“在哪里 [key2] = @p1 和 [key2] = @p2”。

怎么做?似乎正确的方法是将 [key2] 与 null 进行比较。例如,如果您想从 tblSecurityMasterType 中获取 Name 为 NULL 的所有行,这将是错误的方法:

string NameNull = null;
from sm in db.tblSecurityMasterType 
     where sm.Name == NameNull
     select sm;

您将需要改用此查询:

from sm in db.tblSecurityMasterType 
     where sm.Name == null
     select sm;

它在这里描述:http: //smsohan.com/blog/2008/08/05/comparing-with-null-in-where-clause-in/

于 2019-02-20T13:52:47.830 回答