MySQL 数据库设计问题

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

我有一些基本的 DB 设计问题,我想在我完成并绘制所有 DB 关系之前弄清楚它们。

问题一

我有两个表,第一个表包含第二个表的一个实例。我将使用 Entity Framework ,并希望从 table2 访问 table1,并从 table1 访问 table2 .

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

mysql workbench diagram

问题二

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

enter image description here

如果需要更多说明,请告诉我。

最佳答案

正如 ypercube 指出的那样和 JesseB我认为您只需要 1..n 关系。

使用 Entity Framework 4.1(和 POCO Code First),您所需要的只是一个声明此关系的映射,例如

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

请在此处找到完整且有效的代码。如果启动,它将创建一个包含所有需要的外键的数据库。您会看到您需要的唯一外键是 words 表中的 image_id。 Entity Framework 能够将 Word 的集合注入(inject)到任何 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
        }
    }
}

对于多对多关系,只需使用像这样的映射

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 创建表和外键。

如果您更喜欢从数据库开始,请考虑扩展 Entity Framework Power Tools CTP1,您可以从 Extension Manager 下载它:它能够从数据库生成 POCO 类。

关于MySQL 数据库设计问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8460933/

相关文章:

MySQL + 加载数据 INFILE + 变量路径

sql-server - 使用 Entity Framework 管理数据库索引的正确方法

C# EF ASP.NET Web API 超时 - 如何调用长时间运行的查询?

mysql - 连接表上的 Rails SQL 查询

php - 我的 MySQL 数据库被删除,我认为这是 SQL 注入(inject),我哪里错了?

asp.net-mvc - 填充导航属性的导航属性

database-design - FaceBook搜索:它的技术要求和创新功能有哪些值得关注?

database-design - Core Data 比 SQLite 更适合服务器客户端数据库设计吗?

c# - SQL Server 如何处理并发请求?

mysql - 喜欢的帖子设计细节