none
EF5 Auto-incrementing Ids on demand

    Question

  • Hi.

    When I have an entity model with an Id(int), Entity Framework can(and by default will) automatically generate that Id for me.

    class Example
    {
        int Id { get; set; }
        string SomeProperty { get; set; }
    }

    So this code

    DbContext.Entities.Add( new Example { SomeProperty = "SomeValue" } );

    DbContext.SaveChanges();

    Would save the following object in my database: 

    [ Id = 0, SomeProperty = "SomeValue" ]

    EF automatically assigned an Id for the object. And that's fine.

    If I run the same exact code again, I will find the following object stored: 

    [ Id = 1, SomeProperty = "SomeValue" ]

    As expected the next available Id was 1, and that's the one EF assigned the new object.

    Now, if I wipe out my database, and try to restore it(with the same exact IDs, etc) from an XML backup, I would run this code: 

    DbContext.Entities.Add(
        new Example {
            Id = 0,
            SomeProperty = "SomeValue"
        }
    );
    
    DbContext.Entities.Add(
        new Example {
            Id = 1,
            SomeProperty = "SomeValue"
        }
    );

    Will I have the objects restored like this?

    [ Id = 0, SomeProperty = "SomeValue" ]

    [ Id = 1, SomeProperty = "SomeValue" ]

    The answer is no. EF doesn't care if I explicitly specify the Id property or not. It will overwrite it anyway, with the Id it sees fit.

    I could use data-annotations or fluent API to disable this behavior altogether, but that's not an option as I need the functionality. I just have to be able to override it under certain circumstances. 

    Does EF support this?


    Teo Selenius


    • Edited by Selte Friday, June 14, 2013 1:56 PM
    Friday, June 14, 2013 1:55 PM

Answers

  • An identity column is a column that is generally used as a primary key when the key does not matter.  If you need to set the key yourself then the key itself should have some significance.  I am not sure why you need to restore your database with specific values for the keys.  If this is a requirement then you need to have a method to create the keys and have those keys unique which is very difficult to maintain.  

    Bottom line is that you either use identity or not.  If you do you are stuck with its way of creating the keys and you cannot override that behaviour.

     

    Lloyd Sheen

    • Marked as answer by Selte Saturday, June 15, 2013 12:30 PM
    Saturday, June 15, 2013 12:00 PM

All replies

  • Its not EF that is doing this. You have an identity column in your database and the database server is doing it.  Think about if there is one other person using the database.  If it were EF doing the increment first how would EF know about the next Id number, and if there were more than one person then the chances of two people getting the same Id while slim are there as a problem.

    You will not get  the Id number until you SaveChanges.  That is when the database assigns the Id and that is passed back to you.

    Again you have not said if you are using an Identity column but if you do you can not override that.


    Lloyd Sheen

    Friday, June 14, 2013 3:53 PM
  • Its not EF that is doing this. You have an identity column in your database and the database server is doing it.  Think about if there is one other person using the database.  If it were EF doing the increment first how would EF know about the next Id number, and if there were more than one person then the chances of two people getting the same Id while slim are there as a problem.

    You will not get  the Id number until you SaveChanges.  That is when the database assigns the Id and that is passed back to you.

    Again you have not said if you are using an Identity column but if you do you can not override that.


    Lloyd Sheen

    Yes, my understanding is that EF maps [Key] attributes into identity columns. If there's no way to manually set the value of such a column, then can you recommend an alternative solution? I have to use int datatype as the Id, because I'm processing millions of records on a relatively old server machine, thus performance optimizations are critical.


    Teo Selenius

    Friday, June 14, 2013 8:25 PM
  • Hi Teo;

    The identity column is updated in Entity Framework immediately after the save changes has occurred. If you have a reference to that entity all you need is to access the identity column and you will have the value assigned to it from SQL server.

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Saturday, June 15, 2013 2:32 AM
  • Hi Teo;

    The identity column is updated in Entity Framework immediately after the save changes has occurred. If you have a reference to that entity all you need is to access the identity column and you will have the value assigned to it from SQL server.

      


    Fernando (MCSD)

    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Hi.

    Thanks for the reply, but obtaining the Id after SaveChanges has been called is not the issue here, but rather forcing SaveChanges to ignore the fact that Id column is an identity, and use the Id I have specified instead of auto-generating one.

    I'm looking for EF support for something like this: 

    if(User_Has_Explicitly_Specified_A_Value_For_An_Identity_Column)
    
    {
    
        ChangeColumnTypeFromIdentityToNormal();
    
        InsertRecordWithUserProvidedId();
    
        ChangeColumnTypeBackToIdentity();
    
    }
    
    else
    
    {
    
        InsertRecordAndLetDatabaseAutoGenerateId();
    
    }

    I just need to be able to forcibly insert a record with a specific Id from time to time. The question really is that does EF support it, or no. If no, then I'll just think of something else.

    Thanks.


    Teo Selenius

    Saturday, June 15, 2013 9:59 AM
  • An identity column is a column that is generally used as a primary key when the key does not matter.  If you need to set the key yourself then the key itself should have some significance.  I am not sure why you need to restore your database with specific values for the keys.  If this is a requirement then you need to have a method to create the keys and have those keys unique which is very difficult to maintain.  

    Bottom line is that you either use identity or not.  If you do you are stuck with its way of creating the keys and you cannot override that behaviour.

     

    Lloyd Sheen

    • Marked as answer by Selte Saturday, June 15, 2013 12:30 PM
    Saturday, June 15, 2013 12:00 PM
  • An identity column is a column that is generally used as a primary key when the key does not matter.  If you need to set the key yourself then the key itself should have some significance.  I am not sure why you need to restore your database with specific values for the keys.  If this is a requirement then you need to have a method to create the keys and have those keys unique which is very difficult to maintain.  

    Bottom line is that you either use identity or not.  If you do you are stuck with its way of creating the keys and you cannot override that behaviour.

     

    Lloyd Sheen

    Alright, thanks.

    Teo Selenius

    Saturday, June 15, 2013 12:30 PM