有趣的LinqToSql行为

Ben*_*son 3 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;
Run Code Online (Sandbox Code Playgroud)

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

SELECT Field1, Field2 //etc
FROM WaveFiles
WHERE 1=0
Run Code Online (Sandbox Code Playgroud)

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

SELECT Field1, Field2 //etc
FROM WaveFiles
WHERE EmployeeID IS NULL
Run Code Online (Sandbox Code Playgroud)

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

有没有人知道是否有办法保持LinqToSQL中的关联,但停止这种行为.我能想到的一个解决方法是使用一个名为IsSystemFile的计算字段,如果employeeid为null则将其设置为1,否则为0.然而,这似乎是一个解决LinqToSQl的奇怪行为的黑客攻击,我宁愿在DBML文件中做一些事情或者在外键约束上定义一些可以防止这种行为的东西.

Kel*_*tex 5

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

[Column(Storage="_employeeid", DbType="Int")]
Run Code Online (Sandbox Code Playgroud)

并不是:

[Column(Storage="_employeeid", DbType="Int NOT NULL")]
Run Code Online (Sandbox Code Playgroud)