Entity Framework:为什么DbContext是具体类而不是抽象类?

4

我想知道为什么使用Entity Framework时核心类DbContext是一个具体类而不是抽象类。

事实上,我们从未直接使用这个类,只有通过继承它来使用。

难道将其声明为抽象类不是更清晰吗?它作为具体类的原因是什么?


“确实,我们从不直接使用这个类,只有通过继承它来使用。” - 我经常直接使用它。例如,调用 SaveChangesAsync 就是直接使用它的实现。当然,它也有虚方法,但它确实有自己的工作要做。 - user1017882
2个回答

3

只有做出这个决定的人才能确定。但是请注意,在DbContext中没有任何行为是必须由子类提供的,因此如果您将其定义为抽象类 - 这只是因为您想防止直接使用它。但是它仍然可以被直接使用:

using (var ctx = new DbContext("EntityConnectionString")) {
    var errors  = ctx.Set<Error>().ToArray();
    Console.WriteLine(errors.Length);
}

如果您传递实体连接字符串(或在app.config中的名称),它可以从您的emdx模型构建模型(并且它也可以直接用于其他情况)。通过这样做,您可以像往常一样进行查询、保存更改等操作,而不是声明DbSet属性,您只需使用Set<T>方法。
由于单独使用时它没有问题,我认为没有太多理由通过使其抽象来阻止它。

“只有做出这个决定的人才能告诉你确切答案。” 这是一句很棒的话。EF库的开发人员才能解释设计决策。 - CodeNotFound
请注意,在DbContext中没有抽象方法。这个类的缺少抽象方法并不能告诉我们太多信息,因为按照定义,如果该类有这样的方法,它就已经是abstract了,所以原始的问题也不会被问到。 - Damien_The_Unbeliever
@Damien_The_Unbeliever 是的,那个措辞有点令人困惑。 - Evk

2

……我们从不直接使用这个类……

虽然通常是通过从它派生类型并添加其他基于DbSet的属性来使用它,但它也可以单独使用:

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

namespace PlayAreaCSCon
{
    class Program
    {
        static void Main(string[] args)
        {
            var mb = new DbModelBuilder();
            mb.RegisterEntityType(typeof(Foo));
            var pinfo = new DbProviderInfo("System.Data.SqlClient", "2008");
            var ctx = new DbContext("Server=.;Database=Flange;Integrated Security=SSPI;",
                     mb.Build(pinfo).Compile());
            ctx.Set<Foo>().Add(new Foo { ID = 1 });
            ctx.SaveChanges();
            Console.ReadKey();
        }
    }

    public class Foo
    {
        public int ID { get; set; }
    }
}

我在我的Flange数据库中创建了一张Foos表,并插入了一行数据。由于它本身完全可用,如果用户选择这样做,没有任何理由阻止他们使用它。


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