在实体框架中,我如何将通用实体添加到其相应的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方法,它似乎应该是有用的,但我不确定它是如何工作的
您可以考虑这样的泛型类:
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);
…不用担心字体的问题。当然,您应该输入一个已知的实体类型。