我有一些基本的数据库设计问题,我想让他们澄清之前,我通过并得出所有的数据库关系。
问题1
我有两个表,其中第一个包含第二个实例。我将使用实体框架,并希望从table1访问table2,从table2访问table1
我的想法是有一个从table1table2的外键,另一个从table2table1的外键。将链接从table1添加到table2似乎有效。但是,当我试图添加第二个链接(从table2table1)时,MySQL Workbench添加了两个链接,而不是一个。我在想我做错了什么,因为我的理解是应该只添加一个链接。是我的设计错了,还是应该删除正在添加的第二个链接?
问题2
接下来,我尝试实现一个连接表。table1的实例可以有很多table2的实例,反之亦然,因此连接表似乎是实现这一点的必要结构。MySQL允许我创建Identifying RelationshipNon-Identifying Relationship,但我不确定使用哪个。有什么想法吗?
如果需要进一步澄清,请告诉我。

最佳答案

正如ypercubeJesseB所指出的,我认为你所需要的只是1.n的关系。
对于EntityFramework4.1(首先是POCO代码),您只需要一个声明这种关系的映射,比如

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

请在这里找到一个完整的工作代码。如果启动,它将创建一个包含所有所需外键的数据库。您将看到您需要的唯一外键是image_id表中的words。实体框架能够将Words的集合注入任何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:它能够从数据库生成POCO类。

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

10-16 06:54