簡體   English   中英

在查詢中包括父母和孩子?

[英]Include parent and child in query?

我有兩個具有一對多關系的實體,例如:

客戶1 ...... *預訂

 public class Customer
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public List<Booking> Bookings { get; set; }
    }


  public class Booking
    {
        [Key]
        public int Id { get; set; }
        public string Title{ get; set; }
        public DateTime BookingDate { get; set; }
        public int? CustomerId { get; set; }
        public Customer Customer { get; set; };

    }

如果_context是DbContext,則以下兩個查詢最終以循環依賴關系結束。

_context.Customers.Include(x=> x.Bookings).ToList();

要么

_context.Bookings.Include(x=> x.Customer).ToList();

問題是,如果必須在B的查詢中包括實體A,反之亦然,我們如何查詢這些相互依存的關系呢?

您可以使用System.ComponentModel.DataAnnotations.Schema命名空間中定義的ForeignKey屬性。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace ParentChild
{
    public class Customer
    {
        [Key]
        public int? Id { get; set; }
        public string Name { get; set; }
        public virtual List<Booking> Bookings { get; set; }
    }

    public class Booking
    {
        [Key]
        public int? Id { get; set; }
        public string Title { get; set; }
        public DateTime? BookingDate { get; set; }
        public int? CustomerId { get; set; }
        [ForeignKey("CustomerId")]
        public virtual Customer Customer { get; set; }
    }

    public class ParentChildDbContext : Microsoft.EntityFrameworkCore.DbContext
    {
        public ParentChildDbContext(String connectionString)
        {
            ConnectionString = connectionString;
        }

        public String ConnectionString { get; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(ConnectionString);

            base.OnConfiguring(optionsBuilder);
        }

        public DbSet<Customer> Customer { get; set; }

        public DbSet<Booking> Booking { get; set; }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var dbContext = new ParentChildDbContext("server=(local);database=ParentChild;integrated security=yes;");

            var data = dbContext.Customer.Include(p => p.Bookings).ToList();

            Console.WriteLine("Customer: {0}, Bookings: {1}", data.First().Name, data.First().Bookings.Count);

            Console.ReadKey();
        }
    }
}

另外,我為此測試創建了一個數據庫:

create database ParentChild
go

use ParentChild
go

create table Customer
(
    Id int not null identity(1, 1),
    Name varchar(50) not null
)

create table Booking
(
    Id int not null identity(1, 1),
    Title varchar(50) not null,
    BookingDate datetime not null,
    CustomerId int not null
)
go

insert into Customer values ('Parent')
go

insert into Booking values ('First booking', getdate(), 1)
go

輸出結果:

客戶:父母,預訂:1

對於我在使用Asp.Net Core時遇到的上述問題,一種可能的解決方案是告訴MVC選項來處理引用循環,如下所示:

 services.AddMvc()
                .AddJsonOptions(options =>
                {
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                });

我向EF核心團隊提出了一個問題 ,以回答是否應該在用戶端處理引用循環或應由EF Core處理引用循環。 得到答復后將更新答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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