[英]Entity framework relationships
我有以下三个实体:
public class Dog
{
public int DogId { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public bool Checked { get; set; }
public string DogImage { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
public class Event
{
public int EventId { get; set; }
public string EventName { get; set; }
public string EventLocation { get; set; }
public string EventType { get; set; }
public string EventDate { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
public class Result
{
public int ResultId { get; set; }
public int Track { get; set; }
public int Obedience { get; set; }
public int Protection { get; set; }
[ForeignKey("Dog")]
public int DogId { get; set; }
public virtual Dog Dog { get; set; }
[ForeignKey("Event")]
public int EventId { get; set; }
public virtual Event Event { get; set; }
}
我以前一直在这里得到帮助,以便进行这样的设置。 尝试创建多对多关系时出现实体框架错误
因此,我现在想的result
是将这些类联系在一起的“胶水”,其中包含指向其他两个表的外键。
我几天来一直在努力实现以下目标:
可以说我创建了一个这样的事件:
[HttpPost]
public ActionResult CreateEvent(Event newEvent)
{
newEvent.EventDate = newEvent.EventDate.ToString();
_ef.AddEvent(newEvent);
return View();
}
现在,我想下一步将是向此事件添加狗的列表,并且为了做到这一点,我需要以某种方式使用我的结果类,因为那是“胶水”类。 请让我知道我是否在正确的轨道上。
我只是使用fluent方法完成此操作的(当我发现我发现您可以使用fluent进行所有操作时,但不能使用批注,因此我没有研究它们),以下内容在我的Unit
实体之间创建了很多对很多和我的UnitService
实体:
modelBuilder.Entity<Unit>()
.HasMany<UnitService>(u => u.Services)
.WithMany(us => us.Units);
此代码位于protected override void OnModelCreating(DbModelBuilder modelBuilder)
方法中。
在您的情况下, Event
是Unit
而Dog
是UnitService
。
哎呀,您根本不需要它,您的“联接”表就是您的结果表,就我而言,我不在乎联接表,因此它全都隐藏了。 也许像这样:
modelBuilder.Entity<Result>()
.HasMany<Event>(e => e.Results);
modelBuilder.Entity<Result>()
.HasMany<Dog>(d => d.Results);
进行多对多的关系(例如您的工作方式)并不是一个好主意。 看这里
为了获得正确的多对多关系(以正确的方式映射到数据库中),它没有陷阱,我可以这样尝试:
public class Dog {}
public class Event {}
public class Result {}
// This is a linking table between Dog and Results
public class DogResult
{
public int Id {get;set;}
public int DogId {get;set;}
public int ResultId {get;set;}
}
// This is a linking table between Events and Results
public class EventResult
{
public int Id {get;set;}
public int EventId {get;set;}
public int ResultId {get;set;}
}
现在,当您编写查询时,您可以执行以下操作:
using (var context = new DbContext())
{
var dogs = context.Dogs();
var dogResults = context.DogResults();
var results = context.Results();
var dogsAndResults = dogs.Join(
dogResults,
d => d.Id,
r => r.DogId,
(dog, dogResult) => new { dog, dogResult })
.Join(
results,
a => a.dogResult.ResultId,
r => r.Id,
(anon, result) => new { anon.dog, result });
}
看起来有点讨厌,但它会给您返回一个包含Dog
及其相关Result
的匿名对象的列表。 但是显然最好在存储过程中执行此操作:
using (var context = new DbContext())
{
var results = context.Database.ExecuteStoreQuery<SomeResultDto>("SELECT * .... JOIN ... ");
}
这很干净,因为您正在使用SQL。
这是一种更复杂的处理方式。 但是性能要高得多,尤其是如果您完全了解实体框架如何执行LINQ。
显然,如果要创建以下链接:
using (var context = new DbContext())
{
context.Dogs.AddRange(dogs); // dogs being a list of dog entities
context.Results.AddRange(results); // events being a list of results entities
context.DogResults.AddRange(dogResults); // a list of the links
}
如何创建这些链接完全取决于您。 要将其也转换为存储,您需要创建一些自定义的用户定义表类型并将其用作表值参数。
var dogResults = dogs.SelectMany( d => results.Select ( r => new DogResult { DogId = d.Id, ResultId = r.Id } ) );
那是LINQ查询的野兽,基本上它会获取每条狗并将其链接到每条结果。 在LinqPad运行它,并Dump
值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.