Search code examples
c#databaseentity-frameworkentity-relationship

How to write nullable properties for EF6 table definition class with C#?


I want to write an C# class to describe a database table with an relation to itself, later to be used with Entity Framework 6.

Entity relation diagram of Contacts table

I have the following C# code to implement the above shown table:

public class Contact
{
    /// <summary>
    /// Unique identifier of the contact.
    /// </summary>
    public string ContactId { get; set; }

    /// <summary>
    /// Gets or sets the name of the contact.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Defines whether the contact belongs to another contact (e.g.,
    /// parents, organization).
    /// </summary>
    public virtual Contact BelongsToContact { get; set; }
}

Now, I want to mark BelongsToContact as Nullable, as this property is not required. There may be some contacts that belongs to other contacts, but there are also contact which does not belong to any contact at all. The field should be nullable.

To mark BelongsToContact as nullable, I changed the property from type Contact to Contact? (which is a shorter form of Nullable<Contact>).

public virtual Contact? BelongsToContact { get; set; }

Now, I receive the following error:

Error CS0453 The type 'Contact' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'Nullable'

So: How to mark a property as optional/nullable correctly? The most generic way (without Entity Framework 6 markup when possible).


Solution

  • You should do something like this

        public class Contact
        {
            /// <summary>
            /// Unique identifier of the contact.
            /// </summary>
            public string ContactId { get; set; }
    
            /// <summary>
            /// Gets or sets the name of the contact.
            /// </summary>
            public string Name { get; set; }
    
            /// <summary>
            /// Defines whether the contact belongs to another contact (e.g.,
            /// parents, organization).
            /// </summary>
            [ForeignKey("BelongsToContact")]
            public int? BelongsToContactId { get; set; }
            public virtual Contact BelongsToContact { get; set; }
        }