Dav Evans
Dav Evans

Reputation: 4071

Entity Framework Code First one to many optional with fluent mapping

I have the following C# model where a company exists in a given TimeZone.

[Table("Company")]
public class Company
{
    [Key]
    public int Id { get; set; }

    [StringLength(255)]
    [Required]
    public string Name { get; set; }

    [Required]
    public TimeZone TimeZone { get; set; }

}

[Table("TimeZone")]
public class TimeZone
{
    [Key]
    public int Id { get; set; }

    [StringLength(255)]
    public string Name { get; set; }

}

In my pre-existing SQL database the TimeZone table is a lookup table designed to be referenced by the company table and anything else that needs a TimeZone. For this reason the foreign key in the one to many relationship is in the company.

CREATE TABLE [dbo].[Company](
[Id]            [int] IDENTITY(1,1)     NOT NULL,
[Name]          [nvarchar](500)         NOT NULL,
[TimeZoneId]    [int]                   NOT NULL REFERENCES dbo.TimeZone(Id)) 

CREATE TABLE [dbo].TimeZone(
[Id]            [int] IDENTITY(1,1)     NOT NULL,
[Name]          [nvarchar](500)         NOT NULL)

How can I map his using the EF Fluent API (Im using EF 6) so that I can Company.TimeZone.Name ?

Upvotes: 2

Views: 1889

Answers (2)

Parimal Raj
Parimal Raj

Reputation: 20575

Try something like this :

public class CompanyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder builder)
    {
        builder.Entity<Company>()
            .HasRequired(c => c.TimeZone)
            .WithMany()
            .HasForeignKey(c => c.TimeZoneId);

        base.OnModelCreating(builder);
    }

}

[Table("Company")]
public class Company
{
    [Key]
    public int Id { get; set; }

    public int TimeZoneId { get; set; }

    [StringLength(255)]
    [Required]
    public string Name { get; set; }

    // this will be navigation property
    public TimeZone TimeZone { get; set; }

}

[Table("TimeZone")]
public class TimeZone
{
    [Key]
    public int Id { get; set; }

    [StringLength(255)]
    public string Name { get; set; }

}

Upvotes: 2

javorosas
javorosas

Reputation: 769

You need to declare TimeZone property as virtual for lazy loading, like this:

[Table("Company")]
public class Company
{
    [Key]
    public int Id { get; set; }

    [StringLength(255)]
    [Required]
    public string Name { get; set; }

    [Required]
    public virtual TimeZone TimeZone { get; set; }

}

[Table("TimeZone")]
public class TimeZone
{
    [Key]
    public int Id { get; set; }

    [StringLength(255)]
    public string Name { get; set; }

}

Upvotes: 0

Related Questions