【问题标题】:Get identity value after insert in entity framework while using dependancy injection在使用依赖注入时在实体框架中插入后获取标识值
【发布时间】:2017-11-20 14:09:51
【问题描述】:

我在我的 mvc 核心应用程序中使用实体框架。我也在使用依赖注入技术。现在我想获取新记录标识列的值。我将代码用作..

public interface IGenericRepositoryStudent<T> where T : class
{
    void Add(T item);
}

public class GenericRepositoryStudent<T> : IGenericRepositoryStudent<T> where T : class
{
    private eerp_studentContext _context;
    private DbSet<T> _dbSet;

    public GenericRepositoryStudent(eerp_studentContext context)
    {
        _context = context;
        _dbSet = _context.Set<T>();
    }

    public void Add(T item)
    {
        _dbSet.Add(item);
        _context.SaveChanges();
    }
}

控制器:

public class StudentController : Controller
{
    private IStudentRepository _dbSet;

    public StudentController(IStudentRepository dbSet)
    {
        _dbSet = dbSet;
    }

    public long Add([FromBody]Student _student)
    {
        if (ModelState.IsValid)
        {
            _dbSet.Add(acJournal);
            long _id = _student.id; // value of _id is always 0.
            return _id;
        }
    }
}

【问题讨论】:

  • 只有在对象实际保存到数据库后才回填id,只有在调用SaveChanges之后才会发生,而不是在调用Add之后发生。但是,在每次调用 add 之后调用 SaveChanges 是一个非常糟糕的主意,因为这会导致生成更多的查询。默认情况下,EF 会尝试一次提交所有更改。

标签: entity-framework dependency-injection asp.net-core-mvc


【解决方案1】:

显然,您要添加的每个 T 都有一个主键。在添加 T 并保存更改后,您需要此主键的值。

这意味着,您不能添加每个类的对象,您只能添加具有主键的类。

最简单且类型安全的方法(由编译器检查)是只允许添加具有主键的对象。

// interface of objects that have Id (primary key)
public interface IID
{
    public long Id {get; set;}
}

如果您的数据库使用其他类型作为主键,例如 int 或 GUID,请使用该其他类型作为返回类型

public interface IGenericRepositoryStudent<T> where T : IID
{
    T Add(T item);
}

 public class GenericRepositoryStudent<T> : IGenericRepositoryStudent<T> where T : IID
{
    ...
    public T Add(T itemToAdd)
    {
        T addedItem = _dbSet.Add(item);
        _context.SaveChanges();
        return addedItem
    }
}

用法:

class Student : IID
{
    public long Id {get; set;} // primary key
    ...
}

public class StudentController : Controller
{
    ...
    public T Add([FromBody]Student _student)
    {
        if (ModelState.IsValid)
        {
            return _dbSet.Add(_student);
        }
    }
}

我选择返回完整的 T 而不是仅返回 Id,因为如果您需要添加项的某些属性,则不需要获取刚刚添加的项。除此之外,这只是 DbSet.Add(T) 的返回值

如果你真的想要,只需返回学生 ID。

【讨论】:

    猜你喜欢
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多