3

I have created a very simple project to demonstrate table-per-hierarchy inhertiance. In my unit test which tries to generate the database, i get one of a number of errors depending on the config:

without the Required() method

Map<InActiveUser>(x => x.Requires("IsActive").HasValue(false));
Map<ActiveUser>(x => x.Requires("IsActive").HasValue(true));

delivers:

System.Data.DataException : An exception occurred while initializing the database. See the InnerException for details.
  ----> System.Data.EntityCommandCompilationException : An error occurred while preparing the command definition. See the inner exception for details.
  ----> System.Data.MappingException : 
(6,10) : error 3032: Problem in mapping fragments starting at line 6:Condition member 'User.IsActive' with a condition other than 'IsNull=False' is mapped. Either remove the condition on User.IsActive or remove it from the mapping.

with the Required() method:

Map<InActiveUser>(x => x.Requires("IsActive").HasValue(false).IsRequired());

Map<ActiveUser>(x => x.Requires("IsActive").HasValue(true).IsRequired());

delivers:

System.Data.DataException : An exception occurred while initializing the database. See the InnerException for details.
  ----> System.Data.EntityCommandCompilationException : An error occurred while preparing the command definition. See the inner exception for details.
  ----> System.Data.MappingException : 
(6,10) : error 3023: Problem in mapping fragments starting at lines 6, 13, 19:Column User.IsActive has no default value and is not nullable. A column value is required to store entity data.

From what I understand we should not define the discriminator column/property on the base type, but either way it seems to make no difference with or without the column defined:

  public class User
  {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int Id { get; set; }

    [Required]
    public virtual string Username { get; set; }

    [Required]
    [DefaultValue(true)]
    public bool IsActive { get; set; } //have tried without this property
  }

  public class InActiveUser : User
  {
    public virtual DateTime DeActivatedDate { get; set; }
  }

  public class ActiveUser : User
  {
  }

1 Answer 1

5

You cannot map discriminator as property in the entity. Discriminator defines type of the entity. The reason is clear - discriminator defines instanced type. What should happen if you would be able to change discriminator value at runtime? How should .NET change the type of instanced object?

Define entities as:

public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int Id { get; set; }

    [Required]
    public virtual string Username { get; set; }
}

public class InActiveUser : User
{
    public virtual DateTime DeActivatedDate { get; set; }
}

public class ActiveUser : User
{ }

And this should work:

modelBuilder.Entity<User>()
            .Map<InActiveUser>(x => x.Requires("IsActive").HasValue(false))
            .Map<ActiveUser>(x => x.Requires("IsActive").HasValue(true));
Sign up to request clarification or add additional context in comments.

4 Comments

I run this code and it works so there must be something else not included in your question.
If you use just this code in a new project (as I did it) is it working?
I had tried this "From what I understand we should not define the discriminator column/property on the base type", it turns out the database had been created but was in a half-cut state. once i deleted it and ran it without the Required() method and no discriminator property, it has worked.
If anyone gets this issue in the designer, this answer also applies there. The discriminator should not be used in the Base class as property. Just found out that thanks to this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.