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

Dre*_*rew 5 c# database entity entity-framework

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

public DbSet<Office> Offices { get; set; }
public DbSet<Employee> Employees { get; set; }
Run Code Online (Sandbox Code Playgroud)

我做过的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);
    }
Run Code Online (Sandbox Code Playgroud)

基本上我要强调的两件事是将Office对象传递给方法,并通过显式编写db.Offices将Office添加到Office DbSet:

db.Offices.Add(office);
Run Code Online (Sandbox Code Playgroud)

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

public void Create(object entityToCreate)
{
    db.CorrespondingEntityType.Add(entityToCreate);
    db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

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

我在msdn上看到了关于ObjectSet.AddObject方法的文档,看起来它应该是有用的,但我不确定它是如何工作的.

小智 8

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

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

  }
Run Code Online (Sandbox Code Playgroud)


Ger*_*old 5

如果你有一个扩展方法,比如...

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

...C# 会为你做类型推断。你可以称之为...

db.Create(office);
Run Code Online (Sandbox Code Playgroud)

...无需担心类型。当然,您应该输入已知的实体类型。