IDbSet和DbSet有什么区别?

Sas*_*ade 5 c# entity-framework

有什么区别

public IDbSet<Chrip> Chirps { get; set; } 
Run Code Online (Sandbox Code Playgroud)

public DbSet<Chrip> Chirps { get; set; }  
Run Code Online (Sandbox Code Playgroud)

它们是一样的吗?

Mat*_*int 16

Sam我的答案巧妙地定义了接口和类之间的区别,但在选择要在代码中使用的内容时还有其他注意事项.

具体而言 - 一个类可以实现多个接口,或者可以实现任何接口未定义的方法和属性.

在这种情况下,IDbSet<TEntity>接口定义了类使用的大多数方法和属性DbSet<TEntity>,但不是所有方法和属性.例如,FindAsync,RemoveRangeSqlQuery方法只存在于具体类实现.如果在代码中使用该接口,则在没有首先转换为具体类型的情况下,您将无法使用这些特定方法.

此外,MSDN中的备注部分IDbSet<TEntity>有另一个有趣的观点:

IDbSet<TEntity>最初的目的是允许创建测试双打(嘲笑或假货)DbSet<TEntity>.但是,这种方法存在的问题是,在接口中添加新成员会破坏已经实现接口而没有新成员的现有代码.因此,从EF6开始,不会向此接口添加新成员,建议将DbSet<TEntity>其用作测试双精度的基类.

我认为可以安全地扩展这种思路,说你通常应该使用声明你的属性,DbSet<TEntity>而不是IDbSet<TEntity>除非你有充分的理由不这样做.


Sam*_*ica 2

通常,当类型名称以 an 开头时,I它就是一个接口。这不是一个硬性规则,而只是一个命名约定。

DbSet可能实现IDbSet


假设你有一个这样的界面

public interface IFoo
{
    int Echo(int bar);
}
Run Code Online (Sandbox Code Playgroud)

一个类会实现这样的接口

public class Foo : IFoo
{
    public int Echo(int bar)
    {
        return bar;
    }
}
Run Code Online (Sandbox Code Playgroud)

这意味着您的类Foo必须实现接口规定的每个方法,在本例中是一个名为的方法Echo,它接受 anint作为输入,并返回int.

这允许您以相同的方式对待一堆不同的类,即使您不知道它们是如何实现的。有关详细信息,请参阅多态性