1

I've tried to work this out myself, but i'm not a database guy and it has confused me heavily.

I have two classes (cut down for ease of reading)

public class Project : IModel
{
    //Internal DB Id
    [DataMember]
    public int ProjectID { get; set; }

    //Project No - Auto Generated at service level
    [DataMember]
    public string ProjectNo { get; set; }
}

public class ProjectExtra : IModel
{
    [DataMember]
    public int ProjectID { get; set; }
    [DataMember]
    public string Description { get; set; }
}

These are used to generate my database using EF6, however I need to mark the ProjectID in ProjectExtra as both the PK and the FK, and i cannot work out how to do that with Fluent API.

ProjectExtra is optional, it may exist once for a project, or not at all.

Can someone perhaps point me in the right direction, I have already setup a couple of others in the method

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Project>().HasMany(p => p.Managers).WithMany();
        modelBuilder.Entity<Project>().HasMany(p => p.Clients).WithMany();

}
Ben
  • 1,291
  • 2
  • 15
  • 36
  • 1
    `modelBuilder.Entity().HasKey(t => t.ProjectID); modelBuilder.Entity().HasRequired(p => p.Project).WithOptional();` And you have to add navigation property Project – Roman Marusyk Sep 16 '15 at 11:10
  • There is no project on ProjectExtra, this is my confusion – Ben Sep 16 '15 at 11:11
  • you seem to try to reduce disk space for NULL descriptions when trying to use an extra table just to store description. I don't think it's worth doing so. Just add a Description column to your original Project table and of course use some variable length string type for that column. All NULLs won't be consuming any much disk space, read more here http://stackoverflow.com/questions/3731172/how-much-size-null-value-takes-in-sql-server – Hopeless Sep 16 '15 at 11:15
  • As i pointed out, the models are stripped down for ease of reading, ProjectExtra actually contains more Properties which can be upwards of 4000 characters each, The project is run from places with very slow internet hence the need to separate out the extra so it's only download when it's actually needed. – Ben Sep 16 '15 at 11:17

2 Answers2

1

When we are mapping a one-to-one association with fluent API, we don't need to specify the foreign key. Since EF only supports one-to-one associations on primary keys, it will automatically create the relationship in the database on the primary keys.

First you should add a navigation property Project:

public class ProjectExtra : IModel
{
    [DataMember]
    public int ProjectID { get; set; }
    [DataMember]
    public string Description { get; set; }

    // navigation property to Project
    [IgnoreDataMember]
    public virtual Project Project { get; set; } 
}

And then mapping:

modelBuilder.Entity<ProjectExtra>().HasKey(t => t.ProjectID); 
modelBuilder.Entity<ProjectExtra>().HasRequired(p => p.Project).WithOptional();

Reference: Associations in EF Code First

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
  • Hey, thanks for the reply. I should have mentioned in the post that I was hoping to avoid editing the domain models because they are used in other projects such as WCF services, is there a way to do this without editing them? or is this the only way? – Ben Sep 16 '15 at 12:31
  • 1
    @user1412240 Another possibility is to use partial classes – Roman Marusyk Sep 16 '15 at 12:33
  • 1
    Ok, i guess that would be my best bet. thanks for the replies cleared things up nicely. – Ben Sep 16 '15 at 12:38
  • Glad to have been of help – Roman Marusyk Sep 16 '15 at 12:39
0

You need to modify the both Project and ProjectExtra to make them have reference to each other:

    public class Project : IModel
    {
        //Internal DB Id
        [DataMember]
        public int ProjectID { get; set; }

        //Project No - Auto Generated at service level
        [DataMember]
        public string ProjectNo { get; set; }

        public ProjectExtra ProjectExtra { get; set; }
    }

    public class ProjectExtra : IModel
    {
        [DataMember]
        public int ProjectID { get; set; }
        [DataMember]
        public string Description { get; set; }

        public Project Project { get; set; }
    }

And then change your OnModelCreating like such:

    modelBuilder.Entity<ProjectExtra>().HasKey(p => p.ProjectID);
    modelBuilder.Entity<ProjectExtra>().HasRequired(p => p.Project)
                                       .WithOptional(p => p.ProjectExtra);
Aditya Santoso
  • 1,031
  • 6
  • 19