假设我有两个简单的模型(如下),其中"User"包含指向"UserDetail"(一对一关系)的导航属性:
数据库
CREATE TABLE [dbo].[UserDetail]
(
[UserId] [int] NOT NULL PRIMARY KEY,
[Name] varchar(100) NULL
)
CREATE TABLE [dbo].[User]
(
[UserId] [int] NOT NULL PRIMARY KEY
)
C#.网
[Table("UserDetail"), Schema="dbo"]
public class UserDetail
{
[Key, Required, 数据库Generated(数据库GeneratedOption.None)]
public int UserId { get; set; }
public string Name { get; set; }
// Additional Properties Not Listed
}
[Table("User"), Schema="dbo"]
public class User
{
[Key, Required]
public int UserId { get; set; }
// Additional Properties Not Listed
[ForeignKey("UserId")]
public virtual UserDetail UserDetail { get; set; }
}
现在,我们开始讨论这个问题.NET应用程序使用的是存储库体系 struct ,所以我首先要为"用户"表设置一个查询(默认实体框架行为;延迟加载):
IQueryable<User> users = DataRepository.UserRepository.List(); // 'List()' returns an IQueryable
我在这里的最终目标是简单地添加一个过滤器,该过滤器只会提取没有关联的"UserDetail"记录的"User"(即导航属性为NULL):
users = users.Where(m => m.UserDetail == null); // Also tried (m => m.UserDetail.Equals(null))
var testing = users.ToList();
但是当判断"testing"变量时,query总是返回空的(在数据库中,有"User"记录,其中包含和不包含关联的"UserDetails").根据一些初步研究,这似乎可能是由于延迟加载造成的.为了验证,我try 了以下示例:
users = users.Where(m => m.UserDetail.Name == "UserName");
var testing = users.ToList();
令我惊讶的是,这一切都如期而至;"testing"变量包含"User"记录,其中有一个关联的"UserDetail"记录,其"Name"属性等于"UserName".现在看来,延迟加载不是问题,而是IQueryable比较空导航属性(在SQL查询转换期间?)的潜在问题.
在最后一次测试中,决定try 使用Include方法,看看这是否产生了差异,但它产生的结果与第一次测试相同(即空):
users = users.Include(m => m.UserDetail).Where(m => m.UserDetail == null);
var testing = users.ToList();
所以我现在不知所措,显然没有足够的理解来产生我想要的结果.如果有人知道我在这个问题上遇到了什么问题,我希望能得到任何建议/帮助.
我的最佳猜测是IQueryable查询将导航属性转换为"JOIN"(s)而不是"LEFT JOIN"(s),因此不能用于比较空/空关联记录(这些记录根本不存在).
重述问题:
- 如何在中编写查询.NET/实体框架,该框架将在数据库上执行,以仅提取没有关联的"UserDetail"记录的"User"?
- 为什么IQueryable不能获取我在第一次测试中期望的记录?
- 澄清我在IQueryable功能方面所说的任何错误
提前感谢您的帮助/建议!