在实体框架中,我如何将通用实体添加到其相应的DbSet中,而不需要枚举所有可能的DbSet的开关语句

本文关键字:DbSet 实体 不需要 有可能 语句 开关 枚举 框架 添加 | 更新日期: 2023-09-27 17:53:39

我有两种类型的实体:员工实体和办公室实体,两者之间有一对多的关系,一个办公室有许多员工。对于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将Office添加到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方法做类似的事情。

我从msdn上看到了这个关于ObjectSet的文档。AddObject方法,它似乎应该是有用的,但我不确定它是如何工作的

在实体框架中,我如何将通用实体添加到其相应的DbSet中,而不需要枚举所有可能的DbSet的开关语句

您可以考虑这样的泛型类:

 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);

…不用担心字体的问题。当然,您应该输入一个已知的实体类型。