MySQL数据库设计问题

时间:2011-12-11 00:07:18

标签: mysql entity-framework database-design foreign-keys

我有一些基本的数据库设计问题,我希望在我完成并绘制所有数据库关系之前清除它们。

问题1

我有两个表,第一个将包含第二个表。我将使用实体框架,并希望从table1访问table2,从table2访问table1

我的想法是拥有从table1table2的外键,以及从table2table1的外键。添加从table1table2的链接似乎有效。但是,当我尝试添加第二个链接(从table2table1)时,MySQL Workbench会添加两个链接而不是一个。我在想我做错了,因为我的理解是它应该只添加一个链接。我的设计是错误的,还是应该删除正在添加的第二个链接?

mysql workbench diagram

问题2

接下来,我正在尝试实现一个连接表。 table1的实例可以有许多table2实例,反之亦然,因此连接表似乎是实现此目的的必要结构。 MySQL允许我创建Identifying RelationshipNon-Identifying Relationship,我不确定要使用哪个。有什么想法吗?

enter image description here

如果需要进一步澄清,请告诉我。

1 个答案:

答案 0 :(得分:1)

正如ypercubeJesseB指出的那样,我认为你所需要的只是一个1..n关系。

使用Entity Framework 4.1(和POCO Code First),您只需要一张声明此关系的地图,例如

this.HasRequired(t => t.Image)
  .WithMany(t => t.Words)
  .HasForeignKey(d => d.ImageId);

请在这里找到完整且有效的代码。如果启动它将创建一个包含所有所需外键的数据库。您将在image_id表中看到您需要的唯一外键是words。实体框架能够将Word的集合注入任何Image对象,而不依赖于任何其他外键。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WordAndImages.Entities;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;

namespace WordAndImages
{

    public class Word
    {
        public int Id { get; set; }
        public int ImageId { get; set; }
        public virtual Image Image { get; set; }
        public string Value { get; set; }
    }

    public class Image
    {
        public int Id { get; set; }
        public virtual List<Word> Words { get; set; }
        public string Value { get; set; }
        public Image()
        {
            Words = new List<Word>();
        }
    }


    public class Context : DbContext
    {
        static Context()
        {
            Database.SetInitializer<Context>(null);
        }

        public DbSet<Word> Words { get; set; }
        public DbSet<Image> Images { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new WordsMap());
        }
    }

    public class WordsMap : EntityTypeConfiguration<Word>
    {
        public WordsMap()
        {
            this.HasRequired(t => t.Image)
              .WithMany(t => t.Words)
              .HasForeignKey(d => d.ImageId);
        }
    }


    class Program
    {
        static void Main(string[] args)
        {

            #region Saving a Word with an Image

            var context = new Context();
            context.Database.Delete();
            context.Database.CreateIfNotExists();

            var word = new Word();
            word.Value = "I'm a word";

            var image = new Image();
            image.Value = "I'm an image";

            word.Image = image;

            context.Words.Add(word);
            context.SaveChanges();
            #endregion

            #region Accessing an Image from a Word and viceversa

            var context2 = new Context();

            var recovered_word = context2.Words.Where(w => w.Value == "I'm a word").FirstOrDefault();
            Console.WriteLine(string.Format("I'm the word '{0}' and my image is '{1}'", word.Value, word.Image.Value));

            var recovered_image = context2.Images.Where(w => w.Value == "I'm an image").FirstOrDefault();
            Console.WriteLine(string.Format("I'm the image '{0}' and one of my images is '{1}'", recovered_image.Value, recovered_image.Words.First().Value));

            Console.ReadLine();
            #endregion
        }
    }
}

对于many-to-many关系,只需使用

之类的地图即可
this.HasMany(a => a.Words)
  .WithMany(z => z.Images)
  .Map(m =>
  m.ToTable("Images_Words").MapLeftKey("Word_id").MapRightKey("Image_id"));

并按以下方式修改您的课程

public class Word
{
    public int Id { get; set; }
    public virtual List<Image> Images { get; set; }
    public string Value { get; set; }
    public Word()
    {
        Images = new List<Image>();
    }
}

public class Image
{
    public int Id { get; set; }
    public virtual List<Word> Words { get; set; }
    public string Value { get; set; }
    public Image()
    {
        Words = new List<Word>();
    }
}

如果不使用旧数据库,我首先要设计域对象,然后让ORM创建表和外键。

如果您首选从数据库开始,请考虑扩展实体框架Power Tools CTP1,您可以从Extension Manager下载它:它能够从数据库生成POCO类。