简体   繁体   中英

EF6 code first one to zero or one with Predefined FK property

am working on some legacy code , would to add new table to the DB and it would have two one to zero or one relation ship and I need "for some reason" The ForeignKeys in the new table to be defined as properties and The code :

public class EconomyInfo : Entity
{
     /*other props*/
    [ForeignKey("LogoImage")]
    [Required]
    public int LogoImage_Id { get; set; }
    public virtual Image LogoImage { get; set; }

    [ForeignKey("Organization")]
    [Required]
    public int Organization_Id { get; set; }
    public virtual Organization Organization { get; set; }

}

public class Image : Entity
{
    /*other props*/
    public virtual EconomyInfo Economyinfo { get; set; }
}

public class Organization : Entity
{
  /*other props*/
    public virtual EconomyInfo EconomyInfo { get; set; }

}

public class Entity
    {
        public int Id { get; set; }
    }

Like This EF don't generate migration and give the error

EconomyInfo_LogoImage_Source: : Multiplicity is not valid in Role 'EconomyInfo_LogoImage_Source' in relationship 'EconomyInfo_LogoImage'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.

and the same for the other navigation property and if i add those to lines in the the context class:

modelBuilder.Entity<Organization>().HasOptional(o => o.EconomyInfo).WithOptionalPrincipal();
modelBuilder.Entity<Image>().HasOptional(i => i.Economyinfo).WithOptionalPrincipal();

the migration will be generated without errors but it will be strange like :

public override void Up()
    {
        CreateTable(
            "dbo.EconomyInfoes",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),

                    LogoImage_Id = c.Int(nullable: false),
                    Organization_Id = c.Int(nullable: false),
                    Image_Id = c.Int(),
                    Organization_Id1 = c.Int(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Images", t => t.LogoImage_Id, cascadeDelete: true)
            .ForeignKey("dbo.Organizations", t => t.Organization_Id)
            .ForeignKey("dbo.Images", t => t.Image_Id)
            .ForeignKey("dbo.Organizations", t => t.Organization_Id1)
            .Index(t => t.LogoImage_Id)
            .Index(t => t.Organization_Id)
            .Index(t => t.Image_Id)
            .Index(t => t.Organization_Id1);

    }

i know that i could edit the generated EF migration code to make it specify my needs , but there is no point of wasting hours dealing with EF and then give up and work around it , plus it won't be so practical to work with it later by my colleagues ,thanks in advance

I've just given up and decided to go with the work around as write my own migration for my new entity and tell the context to ignore it from the upcoming generated migration.

So my solution is this:

In the context class :

// Regarding unPossible configuration to make pre defined property as foreign key in one to zero or one relationship
// we wrote our migration and tell the context to ignore our model and its navigation property from other model classes
modelBuilder.Entity<Organization>().Ignore(o => o.EconomyInfo);
modelBuilder.Entity<Image>().Ignore(i => i.Economyinfo);
modelBuilder.Ignore<EconomyInfo>();

Organization class :

public virtual EconomyInfo EconomyInfo { get; set; }

Image class :

public virtual EconomyInfo Economyinfo { get; set; }

Manual written migration :

    using System;
    using System.Data.Entity.Migrations;

    public partial class EconomyInfo : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.EconomyInfoes",
                c => new
                {
                    Id = c.Int(nullable: false, identity: true),

                    LogoImage_Id = c.Int(nullable: false),
                    Organization_Id = c.Int(nullable: false),

                })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Images", t => t.LogoImage_Id)
                .ForeignKey("dbo.Organizations", t => t.Organization_Id)
                .Index(t => t.LogoImage_Id)
                .Index(t => t.Organization_Id);

        }

        public override void Down()
        {
            DropForeignKey("dbo.EconomyInfoes", "Organization_Id", "dbo.Organizations");
            DropForeignKey("dbo.EconomyInfoes", "LogoImage_Id", "dbo.Images");
            DropIndex("dbo.EconomyInfoes", new[] { "Organization_Id" });
            DropIndex("dbo.EconomyInfoes", new[] { "LogoImage_Id" });
            DropTable("dbo.EconomyInfoes");
        }
    }

You may refer to this question also for more info How do I specify the foreign key in a one-to-one/zero relationship?

Note: I applied my written migration to database works fine, try to generate new migration, also works as expected, but not tested working with my new model class from code yet. Hopefully nothing will be messed later,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM