NB我不是在问如何在数据库中查找/筛选实体。我不是在问Find
和Where
之间的区别。我不是在问泛型的含义
根据文档,DbContext
提供了方法Find
和Find<T>
。通常,我会浏览DbSet
,但注意到直接在上下文和DB集上都有Add()
,我想看看如果我也尝试直接在上下文而不是DB集上进行筛选会发生什么。
不过,我还没有找到一个这样的例子。上面的免责声明中提到了许多关于浏览数据库集和差异的信息。但我没有看到任何示例直接在上下文中显示Find()
和Find<T>()
的用法。
这有可能吗?如果有,怎么做?Intellisense是神秘的。。。
它做同样的事情,但不使用DbSet
。它通过指定要获取的type
(实体)来工作。您只需要指定类型,该类型必须与您的DbSet匹配。
这有可能吗?如果有,怎么做?
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options) { }
public DbSet<City> Cities{ get; set; }
public DbSet<State> States { get; set; }
}
并像这样使用:
MyContext context = CreateContext() // Or inject it...
// Will return the City which have id == 5.
object myUntypedCity = context.Find(typeof(City), 5);
// Will return the city which have id == [your guid].
City myTypedCity = context.Find<City>(Guid.NewGuid());
作为旁注;上下文上的Add()
也以同样的方式工作。它将检测它是实体的哪个type
,并将其放在正确的DbSet
上。我不知道如果你有几个DbSet
使用同一个type
会发生什么。
为什么我们在上下文中有一个非泛型Find()DB使用整数作为ID,因此确保ID值不明确不同实体/表之间的
在某些情况下,您可能不公开DbSet
,或者只知道实体的type
。当您没有类型化实体,也不知道它的id(主键)的确切类型时,在编写一些非常通用的代码时,这会非常方便。它可以是CCD_ 19或CCD_。我自己从未在DbContext
上找到Find
的实际用途。
当你在DbSet上使用Find
时,实体的类型是已知的,所以它只需要根据提供的ID来查找。
当您在DbContext上使用Find
时,您必须告诉EF从其已知映射中查找哪个Type
(实体),或者您可以使用定义要搜索的实体的Type
的Generic版本。
为什么要使用这些方法而不是DbSet.Find
?一个例子是,您不想将域的某个方面公开为DbSet
。例如,如果您有一个客户、企业等的数据库集,这些数据库集都包含对Address实体的引用,则需要在该范围之外加载Address的情况并不常见,因此您可能会选择不公开域中的DbSet<Address>
,以免因方便而被滥用。在您的DbContext确实需要定位特定地址的情况下,您可以使用DbContext.Find<Address>(addressId)
来加载它
老实说,我不使用DbContext.Find()
,我甚至不使用DbSet.Find()
,我非常非常喜欢使用IQueryable
和投影。但嘿,这是一种选择。:)