使用Find方法在dbSet中查找记录,而无需使用主键。

34

我有一个用户表:

Users:
 +ID
 +Username
 +...

我想使用myDBContext.Users.Find(Username)来查找用户。在我的当前上下文中,我无法使用他的ID。

我需要使用完整的LINQ查询吗?例如:

var user = from users in myDBContext.Users.Find(Username) 
           where users.Username == username
           select users
我尝试将用户名定义为edmx中的主键,但出现以下错误:

由主要角色“User”引用的属性必须与实体类型“CamelotShiftManagementModel.User”的关系约束的主要角色引用的键完全相同。确保在主要角色中指定所有关键属性。 C:\ Code \ CamelotShiftManagement \ CamelotShiftManagement \ Models \ CamelotDB.edmx 278 11 CamelotShiftManagement

2个回答

63

尝试使用以下方法:

User myUser = myDBContext.Users.SingleOrDefault(user => user.Username == username);
使用SingleOrDefault替代Single。如果用户不存在,则Single会引发错误。而SingleOrDefault将返回null,如果未找到用户,否则将返回User对象。
选择SingleOrDefaultFirstOrDefault 可以使用SingleOrDefaultFirstOrDefault获取用户对象,但在选择使用哪种方法时,请考虑以下几点:
- 如果你有多个用户名相同的用户,并且在执行LINQ查询时期望出现异常,则使用SingleOrDefault,因为如果有多个可用元素,则会引发异常。 - 如果您不想出现异常并且或者不想检查您的集合/数据库是否有重复数据,只想从集合/数据库中获取第一个值,则使用FirstOrDefault,与SingleOrDefault相比具有更好的性能。 FirstOrDefault 通常情况下,当我们需要从集合或数据库中获取单个值(第一个)时,会使用FirstOrDefaultFirst
对于First / FirstOrDefault,在这种情况下,仅从数据库中检索一行,因此它的性能略优于single / SingleOrDefault。差异很小,基本上是不可见的,但是当表包含大量列和行时,此时性能会更加显著。
其他一些备注:
- 如果username是主键,则我认为SingleOrDefaultFirstOrDefault性能没有(明显)区别,因为主键具有索引,对索引列的搜索始终比正常列更快。 - SingleSingleOrDefault将生成常规TSQL,如“SELECT...”。 - FirstFirstOrDefault方法将生成类似于“SELECT TOP 1...”的TSQL语句。

1
使用FirstOrDefault不是更好吗?我对SingleOrDefault方法的理解是它会浏览整个表格以确保只有一个记录符合条件。这可能不是OP想要的。 - Crono
2
@Crono 是的,如果我们考虑到性能问题,FirstOrDefault确实比SingleOrDefault更好。但是在这里,我认为我们应该根据预期结果在这两种方法之间进行选择。如果您只想要单个结果,并且如果有多个相同的序列,则期望出现异常,则使用SingleOrDefault;否则,请使用FirstOrDefault。我会在我的答案中更新这个上下文。 - Jignesh Thakker
2
@Crono,我希望我的更新答案能够详细解释SingleOrDefaultFirstOrDefault的用法。 - Jignesh Thakker

5
我已找到它:
User myUser = myDBContext.Users.Single(user => user.Username == i_Username);

1
没问题,但既然它是你问题的解决方案,你应该接受它作为答案。 - Mahmoud Gamal
1
好的,它告诉我只能在两天后接受它,所以我会等待...谢谢。 - Mortalus
1
@Mortalus 如果我的回答有帮助到你的问题,请查看一下。我只是将 Single 更改为 SingleOrDefault。 - Jignesh Thakker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接