My mapping class looks like the following:

public class EmployeeMap : EntityTypeConfiguration<EFEmployee>
{
    public EmployeeMap()
    {
        HasKey(t => t.Id);
        Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(t => t.HireDate).IsRequired();
        //Property(t => t.JobTitle).IsRequired();
        Property(t => t.Salary).IsRequired();
        //Property(t => t.Certifications).IsRequired();
        Property(t => t.VacationTime).IsRequired();
        Property(t => t.SickTime).IsRequired();
        //Property(t => t.Identity).IsRequired();
        //Property(t => t.Location).IsRequired();
        //Property(t => t.ReportingTo).IsRequired();
        //Property(t => t.Managing).IsRequired();
        ToTable("EFEmployees");
        HasRequired(t => t.EFOffice).WithMany(u => u.EFEmployees);
    }
}

The Property mappings that are commented out are those which produce the following error:

The type 'System.Collections.Generic.List<string>' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method [long unimportant chain of namespaces with ModelConfiguration and TStructuralType].

Well that's not entirely accurate. The error message above is specifically for the mapping of JobTitle and Certifications since those are the two properties which are type List. The other errors are the same except for their corresponding types.

  • Identity is an EFPerson type (EFPerson is a class I made)
  • Location is an EFOffice type (EFOffice is another class I made)
  • ReportingTo is an EFEmployee type (EFEmployee is another class I made)
  • Managing is a List<EFEmployee> type

So apparently all of these types are nullable, which for some reason it doesn't like. Should I be using a different method than IsRequired() for the nullable types? Or should I be adding something to these nullable types which forces them to be non-nullable? I'm a bit confused about how to map these properties.

Edit: Here is the EFEmployee class:

/// <summary>
/// The Class model for the Employee Entity
/// </summary>
public class EFEmployee : EFBusinessEntity
{
    /// <summary>
    /// The hire date of the employee
    /// </summary>
    public DateTime HireDate { get; set; }

    /// <summary>
    /// The list of jobtitles for the employee
    /// </summary>
    public List<string> JobTitle { get; set; }

    /// <summary>
    /// The Employee's salary (note: not attached to jobtitle necessarily)
    /// </summary>
    public int Salary { get; set; }

    /// <summary>
    /// List of Certifications for the employee
    /// </summary>
    public List<string> Certifications { get; set; }

    /// <summary>
    /// Employee's stored up vacation time
    /// </summary>
    public int VacationTime { get; set; }

    /// <summary>
    /// Employee's stored up sick time
    /// </summary>
    public int SickTime { get; set; }

    /// <summary>
    /// The personal information about the employee, stored as a person Entity
    /// </summary>
    public EFPerson Identity { get; set; }

    /// <summary>
    /// The office the Employee works at, stored as an office Entity
    /// </summary>
    public EFOffice Location { get; set; }

    /// <summary>
    /// The Person that the Employee reports to, stored as another Employee Entity
    /// </summary>
    public EFEmployee ReportingTo { get; set; }

    /// <summary>
    /// The list of Employees that this Employee manages, a list of Entities
    /// </summary>
    public List<EFEmployee> Managing { get; set; }

    /// <summary>
    /// Constructor for an Entity. Only requires the properties that cannot be null.
    /// </summary>
    /// <param name="Id"></param>
    /// <param name="TenantId"></param>
    /// <param name="hire"></param>
    /// <param name="titles"></param>
    /// <param name="salary"></param>
    /// <param name="vacationTime"></param>
    /// <param name="sickTime"></param>
    /// <param name="identity"></param>
    /// <param name="location"></param>
    public EFEmployee(Guid Id, Guid TenantId, DateTime hire, List<string> titles, int salary,
        int vacationTime, int sickTime, EFPerson identity, EFOffice location)
    {

        this.HireDate = hire;
        this.Identity = identity;
        this.JobTitle = titles;
        this.Location = location;
        this.Salary = salary;
        this.SickTime = sickTime;
        this.VacationTime = vacationTime;
    }


    public EFOffice EFOffice { get; set; }
}

Sorry about all the XML comments.

1

There are 1 answers

1
jjj On BEST ANSWER

Entity Framework generally maps classes to database tables and properties of your entity classes to database column types depending on your provider. (For example, you can see a mapping of CLR types to SQL Server here though I'm not sure if that's what the EF SQL Server provider uses.) Your error is telling you that EF can't configure maping for those properties with Property because they're not value types (or complex types).

  1. For properties that have types that are your own classes (and are intended to be mapped to other tables), you need to use functions that configure relationships instead. For example:

    HasMany(e => e.Managing).WithRequired(p => p.Manager)
    
  2. I don't think List<string> is a property that's mappable, if you want EF to ignore it, you can use:

    Ignore(t => t.JobTitle)
    

    or you need to create a new class to hold JobTitles and configure a relationship for it.

Usually, you don't even need to map every property and relationship because EF can infer the mappings from your class definition itself.

See