How to turn on identity-insert in .net core

后端 未结 9 1252
日久生厌
日久生厌 2020-12-15 07:12

I made a few tables in EF and entered in some seed data where I give value to a few columns with a primary key. When I run the application I am getting the error message: <

相关标签:
9条回答
  • 2020-12-15 07:43

    Another way is to explicitly open a connection then SET IDENTITY_INSERT <table> ON.

    var conn = context.Database.GetDbConnection();
    if (conn.State != ConnectionState.Open)
        conn.Open();
    
     context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Posts ON");
    
     var post = new WeblogPost()
     {                    
                   Id= oldPost.Pk,  //   <!--- explicit value to Id field
                   Title = oldPost.Title,
                    ...
     };
     context.Posts.Add(post);    
     conn.Close();
    

    Apparently once a connection has been explicitly opened before an EF request, that connection is not automatically closed by EF, so the setting is applied to the same connection context.

    This is the same reason that Steve's response with transactions works as transactions keep a connection alive.

    Note: you don't want to put the connection into a using statement if you plan to use the same context again later in the application/request. The connection has to exist, so the best way to clear the connection context is to .Close() it, thereby returning EF to its default behavior of opening and closing the connection per operation.

    0 讨论(0)
  • 2020-12-15 07:48

    In EF Core 1.1.2, I got this to work with transactions. In my "database initializer" that put seed data into the tables. I used the technique from this EF6 answer. Here's a sample of the code:

    using (var db = new AppDbContext())
    using (var transaction = db.Database.BeginTransaction())
    {
        var user = new User {Id = 123, Name = "Joe"};
        db.Users.Add(user);
        db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT MyDB.Users ON;");
        db.SaveChanges();
        db.Database.ExecuteSqlCommand("SET IDENTITY_INSERT MyDB.Users OFF");
        transaction.Commit();
    }
    
    0 讨论(0)
  • 2020-12-15 07:49

    Another way is to use ExecuteSqlRaw. Unlike ExecuteSqlInterpolated, you do not have to convert your passed string to a formattable string type.

    using (var db = new AppDbContext())
    using (var transaction = db.Database.BeginTransaction())
    {
        var user = new User {Id = 123, Name = "Joe"};
        db.Users.Add(user);
        db.Database.ExecuteSqlRaw("SET IDENTITY_INSERT MyDB.Users ON");
        db.SaveChanges();
        db.Database.ExecuteSqlRaw("SET IDENTITY_INSERT MyDB.Users OFF");
        transaction.Commit();
    

    ` }

    0 讨论(0)
  • 2020-12-15 07:50

    In order to add related entities with an object graph using the DbContext I used a DbCommandInterceptor which automatically sets INSERT_IDENTITY ON for the table in question and then OFF after the insert. This works with IDs manually set and DbContext.SaveChanges. I used it in my integration tests but after a performance optimization maybe it could be suitable for production code in some cases. Here is my answer to a similar SO question which explains the details.

    0 讨论(0)
  • 2020-12-15 07:59

    Use "SET IDENTITY_INSERT [table] ON/OFF" into transaction

        public static void TranslateDatabase(ref BDVContext bdvContext) 
        {
            bdvContext.Foro.RemoveRange(bdvContext.Foro);
            bdvContext.SaveChanges();
    
            using (var transaction = bdvContext.Database.BeginTransaction()) 
            { 
    
                bdvContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT [dbo].[Foro] On");
    
                using (old_balsaContext db = new old_balsaContext()) 
                {
                    long id = 0;
                    foreach (ForoA77 post in db.ForoA77.Where(x => x.Fecha > new DateTime(2000,1,1) & x.IdPadre == 0 ) )
                    {
                        bdvContext.Foro.Add(new Foro 
                        {
                              Id = ++id
                            , ParentId = 0
                            , EditId = 0
                            , IdDomains = 2
                            , UserNick = post.IdUsuario == 1 ? bdvContext.Users.Where(x => x.Id == 2).Single().User : post.Nick?? ""
                            , IdUsers = post.IdUsuario == 1 ? (int?)2 : null
                            , Title = post.Asunto?? ""
                            , Text = post.Texto?? ""
                            , Closed = post.Cerrado?? false
                            , Banned = post.Veto?? false
                            , Remarqued = post.Remarcado?? false
                            , Deleted = false
                            , Date = post.Fecha?? new DateTime(2001,1,1)
                        });
                    }
                }
    
                bdvContext.SaveChanges();
    
                bdvContext.Database.ExecuteSqlRaw("SET IDENTITY_INSERT [dbo].[Foro] Off");
    
                transaction.Commit();
            }
        }
    

    Note, my entityframework was generated by reverse engineering

    0 讨论(0)
  • 2020-12-15 08:06

    Below solution worked for me.(Link) I have added below annotations. and removed [Key] Annotation.

    [KeyAttribute()]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    

    Namespace can be changed according to the entity framework version. For Entity framework core namespace is System.ComponentModel.DataAnnotations.Schema I did not face a data migration since I have tried in a new project.

    0 讨论(0)
提交回复
热议问题