Generate Guid on database but only when not set in entity

c# ef-code-first entity-framework-6 guid

Question

I have a case where I need to add a Guid Property that is NOT the primary key, and that could be shared with several objects in the table.

What I'd like to do is:

  • Generate the Guid on the database when I don't give it a value
  • Set a Guid (instead of generating it) when I have its value

Both of this would be done on Insert only, Updates won't touch these values.

What I have tried:

  • Add the [DatabaseGenerated(DatabaseGeneratedOption.Identity)] attribute: only works when I don't need to set the Guid manually
  • Add the [DatabaseGenerated(DatabaseGeneratedOption.Computed)] attribute: doesn't work when I don't set the Guid manually

I've seen quite a lot about this topic, and the closest thing would be this article: http://www.davepaquette.com/archive/2012/09/23/calculated-columns-in-entity-framework-code-first-migrations.aspx

But we don't (and won't) use Migration in our project, so that doesn't seem fit.

or this SO question, but that would mean generating Guids in .Net (which doesn't seem to be very clean, at least in my opinion): EF, Code First - How to set a custom Guid identity value on insert

Is there a way to generate the Guid Database side, AND set it when I need to in EF Code first?

If not, what would be a good alternative? Is it really a bad idea to generate Guids on the .Net side? (I could go with that if nothing else is possible)

1
2
5/23/2017 12:00:56 PM

Accepted Answer

I will assume that you are using MS-SQL , then you can do the following

To use the execute command

public class YourDbContext: DbContext
{
     public YourDbContext():base("ConnectionString")
     {              
            if (Database.Exists())
            {                   
                Database.ExecuteSqlCommand("if object_id('CT_DefaultGuid') is null alter table YourTable add constraint CT_DefaultGuid default newid() for YourColumn");
            }
     }
}

To set the Id from .Net, you can do the following

  • Create a Base Entity contains Id property
  • In the constructor you check if the Id is empty then initialize it
  • Let all the entities you have to inherits from this class

Your base class should look like

public class BaseEntity
{
     public BaseEntity()
     {
          if(Id==Guid.Empty)
               Id = Guid.NewGuid();
     }

     public Guid Id{get;set;}
}

To use the migration for existing database

  • from PMC => Enable-migrations
  • from PMC => Add-Migration "FirstRun"
  • open the generated migration file and make sure to empty the Up and Down methods ( this will not apply any changes on the database)
  • Add the corresponding alter column fluent code using Sql("") method in the Up method
  • from PMC => Update-Database -Script , to make sure that only sql statement generated is the alter table statement
  • from PMC => once you are sure that the desired statement is the only appearing in the SQL script , then apply : Update-Database.

Your class should like this

public class FirstRun : DbMigration
{    public override void Up()
     {
        Sql("alter table YourTable add constraint CT_DefaultGuid default newid() for YourColumn");
     }
}

I recommend the last approach, it will be executed once, and you can add changes later to your database.

Hope this will help you

1
9/22/2016 7:04:21 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow