So I was trying to access my local (or you may call it "temporary/runtime/RAM") database (using SQLite with EF Core) before actually saving it on hard-drive. Found out that I can access to local myTable
with DbContext.MyTable.Local
but the problem is the auto-increment for ID
was not assigned yet. So can I enforce my local table members to have auto-assigned ID
before executing DbContext.SaveChanges()
? If not, what is the alternative?
Here's my codes:
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
}
}
My model:
class MyClass
{
public int ID { get; set; }
public string Name { get; set; }
public int Amount { get; set; }
}
My 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");
}
}
In EF, if a model has an ID
property as an int, it should automatically set it to PK and auto-increment, unless you specify otherwise. If the question is simply "can I obtain an auto-generated ID without saving to the DB," the answer is no, you cannot.
In order to get the ID for an auto-generated ID column, you must save the changes to the database first. After that, the new record's ID
property will be set.
MyClass newClass = new MyClass() {
Name = "MyName",
Amount = 10
};
_myDbContext.MyClasses.Add(newClass);
_myDbContext.SaveChanges();
//newClass.ID will be set here.
If you're using an auto-generated column, this is just the only way to do it. If you want to set the ID yourself - like using a uuid - you could make that change to the ID column. In the case of a uuid that would involve changing the type of the ID column to string, and you'll want to set a MaxLength
to whatever the length of the thing you choose to use.
class MyClass
{
[MaxLength(50)]
public string ID { get; set; }
public string Name { get; set; }
public int Amount { get; set; }
}
Then you can manually assign the ID before the DB changes have been written.
Also, in this line
_myDbContext.MyClasses.ToList(); // forcing to have all members in "_myDbContext.MyClasses.Local". Otherwise only changed/added etc. members appear.
I'm not sure I understand your logic here, but there's no reason to do this just to save a new record to the database, and doing so will drastically slow down your application as your database grows. As it stands, you're requesting a list of every item in the table, but you're not even saving it to a variable, so this line is doing nothing more than to slow down your program.