在 Entity Framework 中,如何在没有枚举所有可能 DbSet 的 switch 语句的情况下将通用实体添加到其对应的 DbSet?

In Entity Framework, how do I add a generic entity to its corresponding DbSet without a switch statement that enumerates all the possible DbSets?

我有两种类型的实体:员工实体和办公室实体,两者之间存在一对多关系,因此一个办公室有很多员工。对于 EF,在上下文文件中为每个实体创建一个 DbSet:

public DbSet<Office> Offices { get; set; }
public DbSet<Employee> Employees { get; set; }

我做的一个 EF 教程让我为特定实体执行 CRUD 方法。例如,下面的方法创建一个办公室并将其添加到办公室 DbSet(忽略 MVC 的东西——我不再这样做了):

public ActionResult Create([Bind(Include = "Address,BusinessName")] Office office)
    {
        try
        {

            if (ModelState.IsValid)
            {
                db.Offices.Add(office);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

        }
        catch (DataException /* dex */)
        {
            //Log the error (uncomment dex variable name and add a line here to write a log.
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
        }
        return View(office);
    }

基本上我想强调的两件事是将 Office 对象传递到方法中,并通过显式写入 db.Offices:

将办公室添加到 Office DbSet
db.Offices.Add(office);

但是,我需要编写一个可以传入通用实体对象的方法,并将其添加到正确的 DbSet 中。我的方法的粗略想法是这样的(我忽略了所有 MVC 的东西):

public void Create(object entityToCreate)
{
    db.CorrespondingEntityType.Add(entityToCreate);
    db.SaveChanges();
}

假设我有一个 Employee 对象。我可以将这个 Employee 传递给 Create 方法,它可以看到这是一个 Employee,因此它会将它添加到 Employees DbSet。我不知道 EF 是否支持这个。另一种方法是创建一个 switch 语句,这种方式取决于传入的实体类型,我可以直接调用哪个 DbSet 来将实体添加到。但我想避免这种情况,因为我将与更多的实体合作,而不仅仅是这两个。此外,我将不得不为其他 CRUD 方法做类似的事情。

我看到了this documentation from msdn about the ObjectSet.AddObject Method,看起来应该有用,但我不确定它是如何工作的。

您可以考虑像这样的通用 class:

 public class GenericRepository<T> where T : class
 {
    internal YourConext context;
    internal DbSet<T> dbSet;

    public GenericRepository(YourContext context)
    {
        this.context = context;
        this.dbSet = context.Set<T>();
    }

    public virtual void Insert(T entity)
    {
        dbSet.Add(entity);
        context.SaveChanges();
    }

  }

如果你有像...这样的扩展方法

public static void Create<T>(this DbContext db, T entityToCreate)
    where T : class
{
    db.Set<T>().Add(entityToCreate);
    db.SaveChanges();
}

...C# 将为您进行类型推断。您可以将其称为...

db.Create(office);

...无需担心类型。当然你应该输入一个已知的实体类型。