我有一些基本的数据库设计问题,我想让他们澄清之前,我通过并得出所有的数据库关系。
问题1
我有两个表,其中第一个包含第二个实例。我将使用实体框架,并希望从table1
访问table2
,从table2
访问table1
。
我的想法是有一个从table1
到table2
的外键,另一个从table2
到table1
的外键。将链接从table1
添加到table2
似乎有效。但是,当我试图添加第二个链接(从table2
到table1
)时,MySQL Workbench添加了两个链接,而不是一个。我在想我做错了什么,因为我的理解是应该只添加一个链接。是我的设计错了,还是应该删除正在添加的第二个链接?
问题2
接下来,我尝试实现一个连接表。table1
的实例可以有很多table2
的实例,反之亦然,因此连接表似乎是实现这一点的必要结构。MySQL允许我创建Identifying Relationship
或Non-Identifying Relationship
,但我不确定使用哪个。有什么想法吗?
如果需要进一步澄清,请告诉我。
最佳答案
正如ypercube和JesseB所指出的,我认为你所需要的只是1.n的关系。
对于EntityFramework4.1(首先是POCO代码),您只需要一个声明这种关系的映射,比如
this.HasRequired(t => t.Image)
.WithMany(t => t.Words)
.HasForeignKey(d => d.ImageId);
请在这里找到一个完整的工作代码。如果启动,它将创建一个包含所有所需外键的数据库。您将看到您需要的唯一外键是
image_id
表中的words
。实体框架能够将Word
s的集合注入任何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/