Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “如何筛选”;包括「;实体框架中的实体?_C#_Entity Framework_Entity Framework 6 - Fatal编程技术网

C# “如何筛选”;包括「;实体框架中的实体?

C# “如何筛选”;包括「;实体框架中的实体?,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,实体: public class Room { public Room() { this.Reservations = new HashSet<Reservation>(); } public int Id { get; set; } public decimal Rate { get; set; } public int HotelId {

实体:

    public class Room
    {
        public Room()
        {
            this.Reservations = new HashSet<Reservation>();
        }

        public int Id { get; set; }

        public decimal Rate { get; set; }

        public int HotelId { get; set; }

        public virtual Hotel Hotel { get; set; }

        public virtual ICollection<Reservation> Reservations { get; set; }
    }

    public class Hotel
    {
        public Hotel()
        {
            this.Rooms = new HashSet<Room>();
        }

        public int Id { get; set; }

        public string Name { get; set; }

        public virtual ICollection<Room> Rooms { get; set; }
    }

    public class Reservation
    {
        public int Id { get; set; }

        public DateTime StartDate { get; set; }

        public DateTime EndDate { get; set; }

        public string ContactName { get; set; }

        public int RoomId { get; set; }

        public virtual Room Room { get; set; }
    }

  public class ExecutiveSuite : Room
  {
  }

  public class DataContext : DbContext
    {
        public DbSet<Hotel> Hotels { get; set; }

        public DbSet<Reservation> Reservations { get; set; }

        public DbSet<Room> Rooms { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Room>()
                .HasKey(r => r.Id)
                .HasRequired(r => r.Hotel)
                .WithMany(r => r.Rooms)
                .HasForeignKey(r => r.HotelId);

            modelBuilder.Entity<Hotel>()
                .HasKey(h => h.Id);

            modelBuilder.Entity<Room>()
                .HasMany(r => r.Reservations)
                .WithRequired(r => r.Room)
                .HasForeignKey(r => r.RoomId);

        }
    }
但我得到了一个例外:“DbIsOfExpression需要一个表达式参数,该参数具有与类型参数兼容的多态结果类型。”

现在,如果您注意到,我以两种不同的方式实现了它,第一种是通过显式加载相关实体,第二种是通过使用两个不同的查询,我的问题是,有没有一种方法可以加载我的对象图并过滤我“包含”的实体,只需从数据库执行一次行程

请注意,当前无法筛选加载了哪些相关实体。Include将始终引入所有相关实体

请求此功能

为了筛选子集合,您可以尝试
选择要建模或匿名投影的子集合。

var anonymousProjection = dbContext.CustomerEntity
                                 .Where(c => ! c.IsDeleted)
                                 .Select(x=> new 
                                  {
                                       customers = x,
                                       orders = x.Orders.Where(h=>h.IsDeleted)
                                  }).ToList();

过滤包含实体的方法有两种

  • 使用投影(参见@Eldho答案)
  • 使用第三方库
免责声明:我是项目的所有者

EF+查询IncludeFilter允许轻松筛选包含的实体

context.Entry(hotel)
       .Collection(x => x.Rooms)
       .Query()
       .IncludeFilter(y => y.Reservations
                            .Where(z => z is ExecutiveSuite && z.Reservations.Any())
       .Load();
在引擎盖下,库正好做了一个投影

维基:

编辑:回答子问题

你差点就成功了。房间已包含并过滤,但您没有包括预订

var hotel = context.Hotels
    // Include only executive suite with a reservation
    .IncludeFilter(x => x.Rooms.Where(y => y is ExecutiveSuite && y.Reservations.Any()))
    // Include only reservation from executive suite
    .IncludeFilter(x => x.Rooms.Where(y => y is ExecutiveSuite).Select(z => z.Reservations))
    .First();

编辑:回答评论

如何使用包含筛选器包含多级属性

您可以通过指定每个路径(每个IncludeFilter一个)来包括多级

因此
qry.Include(“Rooms.Hotel”)
成为:

qry.IncludeFilter(x => x.Rooms)
   .IncludeFilter(x => x.Rooms.Select(y => y.Hotel))

编辑:回答评论

EF+是否支持dotnet 5.0


是的,它支持dotnet 5.0和EF Core 5.0。但是,对于IncludeFilter,您还应该直接在EF Core 5中查看过滤后的include内置:

我正在考虑为这一点带来一个新的视角。 尽管这不能解决问题,但它可能会帮助您。 使用AutoMapper,您可以在将集合放入目标对象之前过滤它们。我已经设置了我的解决方案,在任何操作之前,所有内容都映射到DTO中,所以我使用AutoMapper作为这些内容的过滤器。
在这两个示例中,只有两个对数据库的查询。首先是酒店,然后是客房和预订。您还想要什么?为什么不在
include()
中包含所有内容?类似于:
context.Hotels.Include(“房间.预订”)
?@sachin包括其他相关实体,然后尽可能使用到数据库的一次行程对这些相关实体进行筛选/排序。@haim770包括其他相关实体,然后尽可能使用到数据库的一次行程对这些相关实体进行筛选/排序。@RandelRamirez,请尝试并查看我所做的编辑,当我尝试在匿名对象中投影它时,我遇到了一个异常尝试一个强类型,如map to dto或viewmodel,就像这样我尝试在没有显式加载的情况下使用它,但似乎不起作用。=>context.hotels.IncludeFilter(h=>h.rooms.Where(x是ExecutiveSuite&&x.Reservations.Any())为什么会这样?我得到了一个不同的结果。我在用它吗correctly@RandelRamirez,我刚做了一个测试,一切似乎都正常。你得到了什么结果?此功能的一个限制是,以前加载的相关实体将始终包含在内(即使它不满足IncludeFilter谓词)。如果您愿意,还可以在我们的GitHub论坛上报告此问题,以使跟踪比使用堆栈溢出更容易:您所说的“不显式加载”是什么意思?您需要使用.Load()或.ToList()(或任何其他LINQ立即数方法)我这里有一个repo,如果您有时间,您可以查看它并看到我试图得到的结果。因为我可能错误地使用了你的api,所以不需要为bug提交文件。谢谢!:)项目名称为FilteringandOrderingRelatedEntities请告诉我新答案是否有效。我从我这边得到了同样的结果。可惜你没有包括一些示例代码。嗯,好吧,AutoMapper就是这样自动工作的。如果您使用ProjectTo(我个人的意见是,如果您要直接访问DB,您真的应该使用它),那么AutoMapper将生成底层表达式树,并对其进行解析。所以,当你在构建AutoMapper配置文件时,你基本上可以在那里“映射”它,然后你就去那里。它在基本的AutoMapper示例中进行了描述。
var hotel = context.Hotels
    // Include only executive suite with a reservation
    .IncludeFilter(x => x.Rooms.Where(y => y is ExecutiveSuite && y.Reservations.Any()))
    // Include only reservation from executive suite
    .IncludeFilter(x => x.Rooms.Where(y => y is ExecutiveSuite).Select(z => z.Reservations))
    .First();
qry.IncludeFilter(x => x.Rooms)
   .IncludeFilter(x => x.Rooms.Select(y => y.Hotel))