我已经使用EF一段时间了,但只使用基本的规范化表格,并且它们之间几乎没有关系。现在我正在寻找分支并遇到一些映射问题,我确信这只是通过一些简单的OnModelCreating()
更改或其他模型属性来解决的。
我正在创建一个网站来管理可能在不同地点发生的事件。每个事件都是一个实体。每个事件都有一些基本的原始属性,但它也有一个虚拟的ICollection<TimeSlot>
。
public virtual ICollection<TimeSlot> TimeSlots
{
get { return mTimeSlots ?? (mTimeSlots = new Collection<TimeSlot>()); }
set { mTimeSlots = value; }
}
TimeSlot
也很简单,它应该代表在特定时间发生的活动集合的容器。
public class TimeSlot
{
private ICollection<TimeSlotItem> mItems;
public virtual ICollection<TimeSlotItem> Items
{
get { return mItems ?? (mItems = new Collection<TimeSlotItem>()); }
set { mItems = value; }
}
[Key]
public virtual int Id { get; set; }
public virtual string Label { get; set; }
}
由于EF无法映射到基本类型的集合(在本例中为字符串),因此我创建了另一个名为TimeSlotItem
的实体,它只是一个字符串实体映射。
public class TimeSlotItem
{
[Key]
public virtual int Id { get; set; }
public virtual string Description { get; set; }
}
我的问题是如何将这一切映射到一起。默认情况下,EF不会正确映射这些,因为当我使用某些事件,时间段和时间段对数据库进行种子处理时,它只会将所有事件映射到其中一个事件(第一个事件),而不会映射到其他事件。我不认为外键设置正确映射。目前可能没有做多对多,但它应该,至少我相信。
我的映射是:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<FaroEvent>()
.HasMany(f => f.TimeSlots);
modelBuilder.Entity<TimeSlot>()
.HasMany(f => f.Items);
}
在ctor中启用了延迟加载。
我的种子是:
protected override void Seed(MyEventsDataContext context)
{
// This method will be called after migrating to the latest version.
var timeSlotItems = new List<TimeSlotItem>
{
new TimeSlotItem {Description = "Do stuff 1"},
new TimeSlotItem {Description = "Do stuff 2"},
new TimeSlotItem {Description = "Do stuff 3"},
};
timeSlotItems.ForEach(t => context.TimeSlotItems.AddOrUpdate(i => i.Description, t));
context.SaveChanges();
var timeSlots = new List<TimeSlot>
{
new TimeSlot
{
Label = "Slot 1",
Items = new Collection<TimeSlotItem> {timeSlotItems[0], timeSlotItems[1], timeSlotItems[2]}
},
new TimeSlot
{
Label = "Slot 2",
Items = new Collection<TimeSlotItem> {timeSlotItems[0], timeSlotItems[1], timeSlotItems[2]}
},
new TimeSlot
{
Label = "Slot 3",
Items = new Collection<TimeSlotItem> {timeSlotItems[0], timeSlotItems[1], timeSlotItems[2]}
},
};
timeSlots.ForEach(t => context.TimeSlots.AddOrUpdate(i => i.Label, t));
context.SaveChanges();
var events = new List<MyEvent>
{
new MyEvent
{
Address = "123 Street Ln",
CampaignId = "abc123",
City = "City",
CreatedDate = DateTime.Now,
EventDate = DateTime.Now,
EventType = "TradeShow",
Name = "Show Name",
ProductInterest = "MyArm",
State = "State",
Zipcode = "12345",
TimeSlots = new Collection<TimeSlot> {timeSlots[0], timeSlots[1], timeSlots[2]}
},
new MyEvent
{
Address = "123 Street Ln",
CampaignId = "abc123",
City = "City",
CreatedDate = DateTime.Now,
EventDate = DateTime.Now,
EventType = "TradeShow",
Name = "Show Name",
ProductInterest = "MyArm",
State = "State",
Zipcode = "12345",
TimeSlots = new Collection<TimeSlot> {timeSlots[0], timeSlots[1], timeSlots[2]}
},
new MyEvent
{
Address = "123 Street Ln",
CampaignId = "abc123",
City = "City",
CreatedDate = DateTime.Now,
EventDate = DateTime.Now,
EventType = "TradeShow",
Name = "Show Name",
ProductInterest = "MyArm",
State = "State",
Zipcode = "12345",
TimeSlots = new Collection<TimeSlot> {timeSlots[0], timeSlots[1], timeSlots[2]}
},
};
events.ForEach(t => context.MyEvents.AddOrUpdate(i => i.Name, t));
context.SaveChanges();
}
答案 0 :(得分:1)
试试这个:
modelBuilder.Entity<FaroEvent>().HasMany(f => f.TimeSlots).WithMany(f => f.Items);
您可以在此处找到更好的解释:http://msdn.microsoft.com/en-us/data/jj591620.aspx#ManyToMany
答案 1 :(得分:1)
为了更好地了解Fluent API并了解如何映射实体,我曾使用Entity Framework Power Tools或Entity Framework Reverse Code-First POCO Generator工具,让工具为我生成课程我定义了我的表在SQL数据库中应该是什么样子。这种方法可以帮助您从Fluent API开始,并更好地理解。
希望有所帮助。