sqlite 使用EF插入到SqlLite数据库的ID始终返回1

zed5wv10  于 2022-11-15  发布在  SQLite
关注(0)|答案(2)|浏览(366)

我有一个简单的联系应用程序,使用SQLLITE作为数据库。我首先使用EF代码来设计它的数据库。当我保存数据时,它的ID如期在数据库中产生(Auto Increment),但SaveChanges方法总是为ID返回1。
我如何才能获得最新的表ID?
DbContext:

public class ApplicationDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        string dbPath = DbPathGenerator.GetDbPath();

        options.UseSqlite($"Data Source={dbPath}/LiteContactsDb.db");
    }

    public DbSet<Person> Persons { get; set; }
    public DbSet<Address> Addresses { get; set; }
    public DbSet<Phone> Phones { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasMany<Address>()
            .WithOne(a => a.Person)
            .HasForeignKey(a => a.PersonId);

        modelBuilder.Entity<Person>()
            .HasMany<Phone>()
            .WithOne(a => a.Person)
            .HasForeignKey(a => a.PersonId);

        base.OnModelCreating(modelBuilder);
    }
}

保存方法:

public bool SaveContact(PersonViewModel personViewModel, PhoneViewModel phoneViewModel, AddressViewModel addressViewModel)
    {
        bool result = false;

        try
        {
            Person person = new Person();

            person.FirstName = personViewModel.FirstName;
            person.LastName = personViewModel.LastName;
            person.Email = personViewModel.Email;

            _context.Persons.Add(person);
            var personId = _context.SaveChanges();

            Phone phone = new Phone();

            phone.PersonId = personId;
            phone.PhoneTitle = phoneViewModel.PhoneTitle;
            phone.PhoneNumber = phoneViewModel.PhoneNumber;

            Address address = new Address();

            address.PersonId = personId;
            address.AddressTitle = addressViewModel.AddressTitle;
            address.AddressString = addressViewModel.AddressString;
            address.PostalCode = addressViewModel.PostalCode;

            _context.Phones.Add(phone);
            _context.Addresses.Add(address);

            _context.SaveChanges();

            result = true;
        }
        catch (Exception ex)
        {
            result = false;
        }

        return result;
    }

**_context.SaveChanges();**始终返回1。

谢谢

u3r8eeie

u3r8eeie1#

SaveChanges的返回值不是新创建的记录的ID,而是更改的次数。因此,如果您插入单个项,则返回值始终为1。
如果您想要访问新插入的对象的id,请检查该对象的id属性。它在插入后更新。

56lgkhnf

56lgkhnf2#

首先,SaveChanges返回受影响的行数,而不是存储对象时生成的任何ID。其次,SaveChanges持久化所有挂起的更改,而不仅仅是单个对象。
DbContext是断开连接的工作单元,而不是数据库连接。在必须加载数据或保存更改之前,它甚至不会保持连接打开。SaveChanges被调用来持久化所有更改,而不仅仅是最新的更改。当发生这种情况时,将打开一个新连接,并且所有更改都保存在单个内部事务中。
这意味着回滚工作单元不需要额外的工作--只是在处理DbContext之前不要调用SaveChanges
最后,不需要单独添加对象。调用.Add(person)会将所有可通过它访问的对象添加到Added状态。当更改被保留时,DbContext将以正确的顺序执行插入操作,并自动修复FK属性。
这意味着在单个一致的“事务”中添加一个人、电话和地址只需要:

var person = new Person {
    FirstName = personViewModel.FirstName,
    LastName = personViewModel.LastName,
    Email = personViewModel.Email
   
    Phone = new Phone {
        PhoneTitle = phoneViewModel.PhoneTitle,
        PhoneNumber = phoneViewModel.PhoneNumber
    },
    
    Address = new Address {
        AddressTitle = addressViewModel.AddressTitle,
        AddressString = addressViewModel.AddressString,
        PostalCode = addressViewModel.PostalCode
     }
}
_context.Persons.Add(person);

...
_context.SaveChanges();

相关问题