使用CodeFirst(EntityFramework)中的Find方法获取非主键

3

我的理解是find方法只接受主键作为参数。如果你要查找的值正好是主键,那么这种情况很好处理。但在我的情况下,我有一个类似于以下示例的类:

 public class Chamber
 {
    [Key]
    public int Id {get;set;}

    public string ChamberName { get; set; }
 }

我想检查在我的上下文或数据库中是否存在给定的 ChamberName。我该如何做?我需要先枚举上下文,然后使用类似于 db.Chambers.where(a=>a.ChamberName.equals... 的调用在数据库中查找它吗?
如果 ChamberName 是我的主键,我可以看到它工作得很好,但实际上并不是这样。
谢谢。
2个回答

4

DbSet中有一个名为Local的属性。你可以先查询这个属性以查找已加载到上下文中的实体。

var entity = db.Chambers.Local.Where(/**/).SingleOrDefault();

if (entity == null)
{
   entity = db.Chambers.Where(/**/).SingleOrDefault();
}

谢谢Eranga。所以没有办法像find那样一次性完成吗?也就是说,先搜索上下文,如果找不到再搜索数据库?感谢你的回答。我之前不知道有Local这个功能。 - Peter Kellner
@PeterKellner Find 方法内部执行类似的操作。也许你可以实现一个可重用的方法。 - Eranga
是的,或者扩展方法。当涉及传递lambda时,我总是在语法上感到困难。 - Peter Kellner
这是什么作用? - AriesConnolly
1
@AriesConnolly 这是一个评论,你可以像这样用 lambda 表达式设置搜索查询:.Where(e => e.ChamberName.Equals("test")) - Codingwiz

2
您不能使用.Find()方法 - 不过怎么样尝试一下这个方法:
public Chamber FindByChamberName(string chamberName) 
{    
   using(MyDbContext ctx = new MyDbContext())
   {
      Chamber result = ctx.Chambers
                          .FirstOrDefault(c => string.Compare(c.ChamberName, chamberName, true));
      return result;
   }
}

您不需要手动枚举任何内容 - 只需通过名称检索第一个出现的房间 - 或没有。

如果您只需要知道特定名称(通过其ChamberName指定)的房间是否存在,可以使用Linq中的.Any()方法:

using(MyDbContext ctx = new MyDbContext())
{
    return ctx.Chambers.Any(c => string.Compare(c.ChamberName, chamberName, true));
}

marc_s,我不相信这会起作用,因为它没有像find一样考虑上下文中的内容。 - Peter Kellner
在将LINQ to Entities翻译为SQL时,“Compare”中的“ignoreCase”参数似乎被忽略了。我更感兴趣的是“false”情况(当SQL Server的默认排序规则=不区分大小写时,进行大小写敏感搜索)。我希望您的代码能够解决这个问题(我以前从未在LTE中使用过“string.Compare”),但它不起作用(我刚测试过)。我想知道是否有任何方法可以通过LTE查询来控制大小写敏感性。您知道吗?在T-SQL中,人们会在WHERE子句中使用“COLLATE SomeCollation”,还是有其他方法? - Slauma
我天真地使用了比较,以为它会起作用。感谢您指出这一点。 - Peter Kellner

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