簡體   English   中英

實體框架 - 查詢僅返回一個結果

[英]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>&nbsp;&nbsp;
                                            </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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM