【问题标题】:Interesting LinqToSql behaviour有趣的 LinqToSql 行为
【发布时间】:2010-06-01 16:22:29
【问题描述】:

我们有一个数据库表,其中存储了一些波形文件的位置以及相关的元数据。表上有一个外键(employeeid)链接到一个员工表。但是,并非所有 wav 文件都与员工相关,因为这些记录的employeeid 为空。我们使用LinqToSQl访问数据库,查询拉出所有非员工相关的wav文件记录如下:

var results = from Wavs in db.WaveFiles
              where Wavs.employeeid == null;

除此之外,不返回任何记录,尽管存在employeeid 为空的记录。在分析 sql server 时,我发现没有返回记录的原因是因为 LinqToSQl 正在将其转换为看起来非常像的 SQL:

SELECT Field1, Field2 //etc
FROM WaveFiles
WHERE 1=0

显然这不会返回任何行。但是,如果我进入 DBML 设计器并删除关联并保存。突然之间完全相同的 LINQ 查询变成了

SELECT Field1, Field2 //etc
FROM WaveFiles
WHERE EmployeeID IS NULL

即如果存在关联,则 LinqToSql 假定所有记录都具有外键的值(即使它可以为空,并且该属性在 WaveFile 实体上显示为可以为空的 int),并且因此构造了一个不会返回任何记录的 where 子句.

有谁知道是否有办法在 LinqToSQL 中保持关联但停止这种行为。我能很快想到的一种解决方法是有一个名为 IsSystemFile 的计算字段,如果employeeid 为空,则将其设置为1,否则设置为0。然而,这似乎有点像解决 LinqToSQl 的奇怪行为的技巧,我宁愿在 DBML 文件中做一些事情,或者在外键约束上定义一些东西来防止这种行为。

【问题讨论】:

    标签: c# sql sql-server linq-to-sql


    【解决方案1】:

    我认为您应该仔细检查您的 dbml 文件。听起来 Linq 不知道 employeeid 是一个可为空的列。或者查看您的 .cs 文件。此列的属性应如下所示:

    [Column(Storage="_employeeid", DbType="Int")]
    

    而不是:

    [Column(Storage="_employeeid", DbType="Int NOT NULL")]
    

    【讨论】:

      【解决方案2】:

      试试这个:

      var results = from Wavs in db.WaveFiles
                    where DbNull.Value.Equals(Wavs.employeeid)
      

      另一种很好的做法是引入一个默认员工,每个波形文件都关联到该员工,而该员工与真正的员工没有关联

      【讨论】:

        【解决方案3】:

        列定义为:

        [Column(Storage="_employeeid", DbType="Int")]
        

        离开关联的方法是从员工实体集合中进行左连接。

        【讨论】:

          猜你喜欢
          • 2017-02-07
          • 2010-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-03
          • 1970-01-01
          相关资源
          最近更新 更多