是否可以强制DbContext.MyTable.Local成员在DbContext.SaveChanges()执行之前分配自动ID? (EFCore + SQLite)

问题描述 投票:0回答:1

因此,我尝试访问本地(或者您可以称其为“临时/运行时/ RAM”)数据库((将SQLite与EF Core结合使用)),然后才将其实际保存在硬盘上。发现我可以使用myTable访问本地DbContext.MyTable.Local,但是问题是ID的自动增量尚未分配。那么我可以在执行ID之前强制我的本地表成员具有自动分配的DbContext.SaveChanges()吗?如果没有,那有什么选择?

这是我的代码:

using System.Linq;

class Program
{
    private static MyDbContext _myDbContext = new MyDbContext();

    static void Main(string[] args)
    {
        MyClass newClass = new MyClass() { Name = "MyName", Amount = 10 };
        _myDbContext.MyClasses.ToList();    // forcing to have all members in "_myDbContext.MyClasses.Local". Otherwise only changed/added etc. members appear.
        _myDbContext.MyClasses.Add(newClass);

        int myNewID = newClass.ID; 
        // I need newClass.ID that has been auto-assigned here, but it's currently integer default so myNewID value is 0

        _myDbContext.SaveChanges();
        int myNewerId = newClass.ID;
        // now have new auto-assigned newClass.ID value but It's too late
    }
}

我的模特:

class MyClass
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Amount { get; set; }
}

我的DbContext:

using Microsoft.EntityFrameworkCore;

class MyDbContext : DbContext
{
    public DbSet<MyClass> MyClasses { get; set; }

    private static bool _created = false;
    public MyDbContext()
    {
        if (!_created)
        {
            _created = true;
            //Database.EnsureDeleted();
            Database.EnsureCreated();
        }
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
    {
        optionbuilder.UseSqlite(@"Data Source=..\TestDB.db");
    }
}
.net sqlite orm entity-framework-core rdbms
1个回答
0
投票

在EF中,如果模型具有ID属性作为整数,则应自动将其设置为PK并自动递增,除非另行指定。如果问题仅是“我可以在不保存到数据库的情况下获取自动生成的ID”,则答案是否定的,您不能。

为了获取自动生成的ID列的ID,必须首先将更改保存到数据库。之后,将设置新记录的ID属性。

MyClass newClass = new MyClass() { 
  Name = "MyName", 
  Amount = 10 
};
_myDbContext.MyClasses.Add(newClass);
_myDbContext.SaveChanges();

//newClass.ID will be set here. 

如果您使用的是自动生成的列,则这是唯一的方法。如果您想自己设置ID(例如使用uuid),则可以在ID列中进行更改。如果是uuid,则需要将ID列的类型更改为字符串,并且您想要将MaxLength设置为您选择使用的对象的长度。

class MyClass
{
    [MaxLength(50)]
    public string ID { get; set; }
    public string Name { get; set; }
    public int Amount { get; set; }
}

然后,您可以在写入数据库更改之前手动分配ID。

也在此行中

_myDbContext.MyClasses.ToList();    // forcing to have all members in "_myDbContext.MyClasses.Local". Otherwise only changed/added etc. members appear.

我不确定我是否在这里理解您的逻辑,但是没有理由仅将新记录保存到数据库中,并且这样做会随着数据库的增长而大大降低应用程序的速度。就目前而言,您正在请求表中每个项目的列表,但是您甚至没有将其保存到变量中,因此此行无非是减慢程序速度。

© www.soinside.com 2019 - 2024. All rights reserved.