有趣的LinqToSql行为

时间:2010-06-01 16:22:30

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

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

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

除非有记录,其中employeeid为null,否则不返回任何记录。在分析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为null则将其设置为1,否则为0。然而,这对于解决LinqToSQl的奇怪行为似乎有些麻烦,我宁愿在DBML文件中做一些事情或者在外键约束上定义一些可以防止这种行为的东西。

3 个答案:

答案 0 :(得分:5)

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

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

而不是:

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

答案 1 :(得分:0)

试试这个:

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

另一种方法和良好做法很好的是引入一个默认员工,其中每个波形文件都与之相关联,与真实员工无关

答案 2 :(得分:0)

该列定义为:

[Column(Storage="_employeeid", DbType="Int")]
离开协会的方式是从员工实体集合中进行左连接。