locked
Bug in EF 4.1 DatabaseGeneratedOption.Computed? RRS feed

  • Question

  • Hello,

    here is simple code which reproduces the issue:

     class Program
     {
      static void Main(string[] args)
      {
       using (var context = new Context())
       {
        context.Database.CreateIfNotExists();
        // Throws NotSupportedException: The store generated pattern 'Computed' 
        // is not supported for properties that are not of type 'timestamp' or 'rowversion'.
       }
      }
     }
    
     public class MyEntity
     {
      public int Id { get; set; }
      public string Name { get; set; }
      public string Value { get; set; }
     }
    
     public class Context : DbContext
     {
      public DbSet<MyEntity> MyEntities { get; set; }
    
      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
       base.OnModelCreating(modelBuilder);
    
       modelBuilder.Entity<MyEntity>()
        .Property(e => e.Value)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
      }
     }
    

    Why is setting Computed on a custom column not supported? It works without any problems when using model first and EDMX so why it is not supported with Fluent API? I think this is a bug. It is necessary feature for using fluent API with an existing database and with complex projects using code first and custom DB initializers.

    Best regards,
    Ladislav


    Saturday, March 26, 2011 11:00 PM

Answers

  • Hi Ladislav,

    I'm back.

    This is actually a limitation in System.Data.Entity.dll, not EF 4.1, where the call to ObjectContext.CreateDatabase or ObjectContext.CreateDatabaseScript will throw this exception when specifying a column is computed, non-numeric and neither a timestamp nor a rowversion field. This is a issue that we’ve fixed but we have not yet released the update.

     

    By model first working I assume you mean that you are able to create the database script through the designer; unfortunately this uses a different code path from ObjectContext.CreateDatabaseScript so it is likely this artificial limitation does not exist.

     

    However, when you use Code First to create the database, there isn’t actually a way to specify how this string column is computed, so it’s likely that you will need to edit the database script in some way before EF is really able to treat the column as computed. One idea is to run custom DDL code inside your initializer, but of course, you will have to wait for us to release this fix first. Another idea is simply to run Code First with an existing database that’s set up to meet your specifications.

     

    Have a nice day.

     


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, March 29, 2011 1:40 AM

All replies

  • Hi Ladislav,

    Welcome!

    I repro your excption, I will consult the product team about this and I will come back if there is any feedbacks, thanks for understanding.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, March 28, 2011 7:32 AM
  • Hi Ladislav,

    I'm back.

    This is actually a limitation in System.Data.Entity.dll, not EF 4.1, where the call to ObjectContext.CreateDatabase or ObjectContext.CreateDatabaseScript will throw this exception when specifying a column is computed, non-numeric and neither a timestamp nor a rowversion field. This is a issue that we’ve fixed but we have not yet released the update.

     

    By model first working I assume you mean that you are able to create the database script through the designer; unfortunately this uses a different code path from ObjectContext.CreateDatabaseScript so it is likely this artificial limitation does not exist.

     

    However, when you use Code First to create the database, there isn’t actually a way to specify how this string column is computed, so it’s likely that you will need to edit the database script in some way before EF is really able to treat the column as computed. One idea is to run custom DDL code inside your initializer, but of course, you will have to wait for us to release this fix first. Another idea is simply to run Code First with an existing database that’s set up to meet your specifications.

     

    Have a nice day.

     


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, March 29, 2011 1:40 AM
  • Hi Alan,

    Is there any update release for above problem ? Let me know if any Fix release updated by microsoft as i am also have same problem what Ladislav is facing. Difference is i am facing problem for the default value of Data type field in my database.

    Thursday, July 14, 2011 7:19 AM
  • Any news on a fix, as I'm still getting the same issue

    Cheers, SteveC.

    Thursday, February 9, 2012 11:48 AM
  • Hi all,

    Not official, but this issue does seem to have been fixed at least as of EF 4.3.1.

    Thursday, June 21, 2012 7:06 PM
  • Hi Alan,

    I am facing a similar problem in my Code First Project. Since as you mentioned Computed columns could not be defiled with Code First approach, I am using a SQl script to mark an existing column computed after Db has been created with Code First. But problem remains as-is, because once my SQL script marks that colum computed, I am not able to save data to that table using DbContext. The obvious reason => EF tries to write to Computed column and then SQL Engine does not allow since you are not supposed to update/write to computed columns.

    The only solution I feel would be to expilictly specify the columns when DBContext updates an entity, but before I opt for this, I wanted to ask if there are any plans of fixing this issue??

    Any response is highly appreciated.

    Thanks,

    Savita


    • Edited by Geeker S Monday, August 6, 2012 9:22 PM
    • Proposed as answer by Geeker S Tuesday, August 7, 2012 6:02 PM
    • Unproposed as answer by Geeker S Tuesday, August 7, 2012 6:02 PM
    Monday, August 6, 2012 9:20 PM
  • For now, I fixed this issue as follows:

    1. Mark the column with Data Annotation : [DatabaseGenerated(DatabaseGeneratedOption.Computed)] and declared it as Nullable (though I need this to be Not Null)

    2. Since EF will not try to save Null in Nullable columns, I later wrote a Sql script to mark this column Not Null and set the formula for computed result.

    Though it is a hack, but works like a charm for now. I am able to save data with a computed column computing values based on formula I specified and EF does not give any problems saving/updating this entity.

    Hope it will help anyone else struggling with same problem.


    • Proposed as answer by Geeker S Tuesday, August 7, 2012 6:02 PM
    • Edited by Geeker S Tuesday, August 7, 2012 6:03 PM
    Tuesday, August 7, 2012 6:01 PM
  • Hi Allen,

    I was wondering if you had any suggestions to this issue:

    I have a string column in an SQL database that gets updated by a trigger, the problem is [DatabaseGenerated(DatabaseGeneratedOption.Computed)] gives me the “Cannot Insert Null value” when I have the column in the database set to Not Null

    It works fine when I set the column to allow nulls, but this is not desirable, I would like to set the column in the database to Not Null and use the DatabaseGeneratedOption.Computed when inserting records.

    Sunday, August 12, 2012 6:13 AM