实体框架外键多表映射

时间:2017-08-01 13:26:29

标签: c# entity-framework

我有这个场景:

public class Application
{
    [Key]
    public string Code { get; set; }
}

public class Table1
{
    [Key]
    public string Table1Code { get; set; }

    [Key, ForeignKey("ApplicationObject")]
    public string Application { get; set; }
    public virtual Application ApplicationObject { get; set; }
}

public class Table2
{
    [Key]
    public string Table2Code { get; set; }

    [Key, ForeignKey("ApplicationObject")]
    public string Application { get; set; }
    public virtual Application ApplicationObject { get; set; }
}

public class Table3
{
    [Key, ForeignKey("Table1Object")]
    public string Table1Code { get; set; }
    public virtual Table1 Table1Object { get; set; }

    [Key, ForeignKey("Table2Object")]
    public string Table2Code { get; set; }
    public virtual Table2 Table2Object { get; set; }

    [Key, ForeignKey("Table1Object")]
    public string ApplicationCodeTab1 { get; set; }

    [Key, ForeignKey("Table2Object")]
    public string ApplicationCodeTab2 { get; set; }
}

在table1和table2中,属性applicationCode必须是key,因为我可以为不同的应用程序使用相同的代码。

在表3中,我引用了表1和表2。如何为ApplicationCode属性添加外键而不重复属性?

例如:

public class Table3
{
    [Key, ForeignKey("Table1Object")]
    public string Table1Code { get; set; }
    public virtual Table1 Table1Object { get; set; }

    [Key, ForeignKey("Table2Object")]
    public string Table2Code { get; set; }
    public virtual Table2 Table2Object { get; set; }

    [Key]
    public string ApplicationCode { get; set; }
}

Table3中的ApplicationCode属性可以同时存在Table1和Table2的外键吗?

1 个答案:

答案 0 :(得分:2)

关键是将ForeignKey属性移动到navigation属性并指定外键列。

像这样:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp6
{

    public class Application
    {
        [Key]
        public string Code { get; set; }
    }

    public class Table1
    {
        [Key]
        [Column(Order = 0)]
        public string Table1Code { get; set; }

        [Key, ForeignKey("ApplicationObject")]
        [Column(Order = 1)]
        public string Application { get; set; }
        public virtual Application ApplicationObject { get; set; }
    }

    public class Table2
    {
        [Key]
        [Column(Order = 0)]
        public string Table2Code { get; set; }

        [Key, ForeignKey("ApplicationObject")]
        [Column(Order = 1)]
        public string Application { get; set; }
        public virtual Application ApplicationObject { get; set; }
    }

    public class Table3
    {
        [Key]
        [Column(Order = 0)]
        public string Table1Code { get; set; }

        [Key]
        [Column(Order = 1)]
        public string Table2Code { get; set; }

        [Key]
        [Column(Order = 2)]
        public string ApplicationCode { get; set; }

        [ForeignKey("Table1Code,ApplicationCode")]
        public virtual Table1 Table1Object { get; set; }

        [ForeignKey("Table2Code,ApplicationCode")]
        public virtual Table2 Table2Object { get; set; }



    }
    class Db: DbContext
    {


        public DbSet<Table1> Table1 { get; set; }
        public DbSet<Table2> Table2 { get; set; }
        public DbSet<Table3> Table3 { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.OneToManyCascadeDeleteConvention>();
            base.OnModelCreating(modelBuilder);
        }

    }
    class Program
    {

        static void Main(string[] args)
        {


            Database.SetInitializer(new DropCreateDatabaseAlways<Db>());

            using (var db = new Db())
            {
                db.Database.Log = m => Console.WriteLine(m);

                db.Database.Initialize(true);


            }

            Console.ReadKey();

        }
    }
}