[英]Entity Framework - Query only returning one result
我有一個包含三個實體的應用程序:事件、事件帶、帶。 我在控制器類中編寫了以下查詢,但它似乎只返回一個結果。 我希望它返回與數據庫中該事件相關聯的所有波段。
// EventController.cs(編輯方法)
var viewModel = new EventUpdateData();
Event et = await _context.Event.Where(e => e.EventId == id)
.Include(b => b.EventBands)
.FirstOrDefaultAsync();
viewModel.Event = et;
viewModel.EventBand = evtBand;
viewModel.Bands = et.EventBands.Select(b => b.Band).ToList();
return View(viewModel);
// 事件更新數據(視圖模型)
public class EventUpdateData
{
public Event Event { get; set; }
public EventBand EventBand { get; set; }
public IEnumerable <Band> Bands { get; set; }
}
// Edit.cshtml(選擇字段的數據庫中所有波段的列表)
<div class="col-sm-2">
<label for="band-list">Bands</label>
</div>
<div class="col-sm-5">
<select name="band-list" id="band-list" class="band-list form-control">
<option value="#">--Please select a band--</option>
@if (Model.Bands != null)
{
@foreach (var band in Model.Bands)
{
<option value="@band.BandId">@band.BandTitle</option>
}
}
</select>
</div>
// Edit.cshtml(與事件相關的所有波段的列表)
<tbody class="bands">
@foreach (var band in Model.Bands)
{
var bandHours = Int32.Parse(band.BandHourlyRate) * Model.EventBand.EventBandHours;
<tr class="event-band" data-bandID="@band.BandId">
<td>
<a href="#">@band.BandTitle</a>
</td>
<td class="band-rate" data-val="@band.BandHourlyRate">
@bandHours
</td>
</tr>
}
</tbody>
// dbo.Band(數據庫)
band_id band_title band_contact band_phone band_rate event_id
1 Green Fields Mike Ellery 07110291029 100 1
2 House Chicks Dave Hart 07111928193 200 1
3 Groove Surfaces Marie Penn 07566910295 150 1
(我希望查詢獲得所有這些頻段)。
// dbo.EventBand
EventBandId EventId BandId EventBandHourlyRate
54 1 2 1
55 1 1 2
56 1 1 2
57 1 2 1
58 1 3 3
59 1 1 1
60 1 1 1
61 1 2 2
62 1 2 2
63 1 1 1
64 1 2 1
// dbo.Event(數據庫)
1 Jenny's Garden Party 14/05/2021 00:00:00 Jenny Wren The Grove
2 Bob's Balloon Party 15/06/2021 00:00:00 Bob The Garden
// 事件.cs
public class Event
{
public int EventId { get; set; }
public string EventTitle { get; set; }
[DataType(DataType.Date)]
public DateTime EventDate { get; set; }
public string EventCustomer { get; set; }
public string EventVenue { get; set; }
public virtual ICollection<Band> Band { get; set; }
public virtual ICollection<EventBand> EventBand { get; set; }
public virtual ICollection<EventCaterer> Caterer { get; set; }
}
// 事件帶.cs
public class EventBand
{
public int EventBandId { get; set; }
public int EventBandHours { get; set; }
public int EventId { get; set; }
public int BandId { get; set; }
public virtual Event Event { get; set; }
public virtual Band Band { get; set; }
}
// 樂隊.cs
public class Band
{
public int BandId { get; set; }
public string BandTitle { get; set; }
public string BandContact { get; set; }
public string BandPhone { get; set; }
public string BandHourlyRate { get; set; }
public virtual ICollection<EventBand> EventBand { get; set; }
}
在仔細查看您的示例代碼后,我認為您的映射可能會混淆 EventBands 和 Bands 的關系。 為什么您同時擁有多對多 (Event.EventBands) 和一對多? (Event.Bands)
EF 可以通過兩種方式表達多對多關系,具體取決於連接表的使用。 由於您想在聯接表中跟蹤小時數,因此需要聯接實體,並且它形成更多的一對多對一關系。 一個事件有許多 EventBands,每個 EventBands 有一個 Band。 如果依賴 EF 的默認基於約定的映射,同時擁有 EventBands 和 Bands 的集合可能會引起一些混亂。 對於具有 Bands 集合的 Event,它會期望 Band 具有 EventId。 它沒有,所以 EF 必須以某種方式映射關系,否則它會進入 EventBand。
使用帶有 EventBandId 和額外屬性的顯式 EventBand 實體,您需要設置映射:
public class Event
{
[Key]
public int EventId { get; set; }
// ...
// public virtual ICollection<Band> Bands { get; set; } <- Remove.
public virtual ICollection<EventBand> EventBands { get; set; } = new List<EventBand>();
}
public class Band
{
[Key]
public int BandId { get; set; }
// ...
public virtual ICollection<EventBand> EventBands { get; set; } = new List<EventBand>();
}
public class EventBand
{
[Key]
public int EventBandId { get; set; }
[ForeignKey("Event")]
public int EventId { get; set; }
[ForeignKey("Band")]
public int BandId { get; set; }
public int EventBandHours { get; set; }
public virtual Event Event { get; set; }
public virtual Band Band { get; set; }
}
EF 應該能夠在沒有太多麻煩的情況下解決此映射,但明確表示並沒有什么壞處。 從事件和樂隊結束:
// Event config.
HasMany(x => x.EventBands)
.WithRequired(x => x.Event); // EF 6
//.WithOne(x => x.Event).Required(); // EF Core
// Band config.
HasMany(x => x.EventBands)
.WithRequired(x => x.Band); // EF 6
//.WithOne(x => x.Band).Required(); // EF Core
或者,從 EventBand 配置:
HasRequired(x => x.Event)
.WithMany(x => x.EventBands);
HaRequired(x => x.Band)
.WithMany(x => x.EventBands);
避免從兩端配置關系,這可能會導致問題。 要么從 Event & Band -> EventBand 映射它,要么從 EventBand -> Event & Band 映射它,而不是兩者都映射。
更新:EF 6 中的示例實體、映射和關系查詢...
實體:
public class Event
{
public int EventId { get; set; }
public string Name { get; set; }
public ICollection<EventBand> EventBands { get; set; } = new List<EventBand>();
}
public class Band
{
public int BandId { get; set; }
public string Name { get; set; }
public ICollection<EventBand> EventBands { get; set; } = new List<EventBand>();
}
public class EventBand
{
public int EventBandId { get; set; }
public int Rank { get; set; }
public virtual Event Event { get; set; }
public virtual Band Band { get; set; }
}
關系配置:
public class EventConfiguration : EntityTypeConfiguration<Event>
{
public EventConfiguration()
{
ToTable("Events");
HasKey(x => x.EventId)
.Property(x => x.EventId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(x => x.EventBands)
.WithRequired(x => x.Event)
.Map(x => x.MapKey("EventId"));
}
}
public class BandConfiguration : EntityTypeConfiguration<Band>
{
public BandConfiguration()
{
ToTable("Bands");
HasKey(x => x.BandId)
.Property(x => x.BandId)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
HasMany(x => x.EventBands)
.WithRequired(x => x.Band)
.Map(x => x.MapKey("BandId"));
}
}
詢問:
[Test]
public void TestEventBandEagerLoading()
{
using (var context = new TestDbContext())
{
context.Configuration.LazyLoadingEnabled = false;
var bands = context.Events
.Include(x => x.EventBands)
.Include(x => x.EventBands.Select(eb => eb.Band))
.ToList();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.