简体   繁体   English

在没有关系的情况下针对EF上下文创建LINQ语句

[英]Creating LINQ statement against an EF Context with no relationships

I cannot wrap my head around how to write a linq query against my EF context to get what I want. 我无法解决如何针对我的EF上下文编写linq查询以获取所需内容的问题。

1) What I have Database with no foreign keys assigned, and a reverse engineered code first entity framework project. 1)我没有分配外键的数据库,以及一个反向工程代码优先实体框架项目。 I tried manually adding virtual classes so EF might create implied foreign keys in the DBcontext, but I get errors on my .Include statements still. 我尝试手动添加虚拟类,以便EF可以在DBcontext中创建隐式外键,但是我的.include语句仍然出现错误。

Without the include the only thing I can think of is to use left joins, but I haven't gotten it down yet. 没有include,我唯一想到的就是使用左联接,但是我还没有把它弄清楚。 In the end there will be 21 tables I have to get data from, but the following table outline encapsulates the majority of issues i'm facing. 最后,我必须从21个表中获取数据,但是下表概述概括了我面临的大多数问题。

Sample data structure: 样本数据结构:

Table Human : HumanId, LastFoodEatenId, FavoriteFoodId, CurrentlyDesiredFoodId 表Human :HumanId,LastFoodEatenId,FavoriteFoodId,CurrentDesiredFoodId

Table Food : FoodId, FoodName, FoodStuff 餐桌食品 :FoodId,FoodName,FoodStuff

Table Toys : HumanOwnerId, ToyId, ToyName 桌上玩具 :HumanOwnerId,ToyId,ToyName

Table Pets : HumanOwnerId, PetId, PetName, PetType 表宠物 :HumanOwnerId,PetId,PetName,PetType

Table PetSurgery : PetId, SurgeryId, SurgeryPerformed 表PetSurgery :PetId,SurgeryId,SurgeryPerformed

2) What I want Given a HumanID, I want a compsite class or something like it from a single query. 2)我想要什么给定HumanID,我希望通过单个查询获得一个compsite类或类似的东西。

Public Class QueryResult
{
  public Human human {get;set;}
  public Food LastEatenFood {get;set;}
  public Food FavoriteFood {get;set;}
  public Food CurrentlyDesiredFood {get;set;}
  public IEnumerable<Toy> Toys {get;set;}
  public IEnumerable<Pet> Pets {get;set;} //Includes surgeries if any
}

Is it even possible to write a single query to get this kind of information in a single db hit? 甚至有可能编写单个查询以在单个数据库命中中获得此类信息? I'd be fine is someone simply confirmed it is't possible. 如果有人简单地确认这是不可能的,那我很好。 Then I can at least request we add relationships to our database. 然后,我至少可以要求我们将关系添加到数据库中。

Thanks in advance, 提前致谢,

You can use linq to query multiple, non-related tables. 您可以使用linq查询多个不相关的表。

I'm going to assume a LOT about your entities, but here we go... 我将假设很多关于您的实体的信息,但是在这里,我们开始...

int humanId = 1234;

using (var context = new MyContext())
{
    var human = (from h in context.Humans
                 join lf in context.Foods on h.LastFoodEatenId equals lf.foodId into lfg
                 from lf in lfg.DefaultIfEmpty() // left join
                 join ff in context.Foods on h.FavoriteFoodId equals lf.foodId into ffg
                 from ff in ffg.DefaultIfEmpty() // left join
                 join cf in context.Foods on h.CurrentlyDesiredFoodId equals lf.foodId into cfg
                 from cf in cfg.DefaultIfEmpty() // left join
                 join p in context.Pets on h.humanId equals p.humanId into pg // group
                 join t in context.Toys on h.humanId equals t.humanId into tg // group
                 where h.humanId = humanId
                 select new QueryResult { human = h, LastEatenFood = lf, FavoriteFood = ff, CurrentlyDesiredFood = cf, Toys = tg, Pets = pg }
                 ).SingleOrDefault();
}

Note: I'm doing this from memory without a syntax checker, so ymmv. 注意:我是在没有语法检查器的情况下从内存中执行此操作的,所以是ymmv。 Adding surgeries should be possible as well, but may require a subquery. 也应该添加手术,但可能需要子查询。

I tried manually adding virtual classes 我尝试手动添加虚拟类

I assume you mean virtual collections . 我认为您的意思是虚拟馆藏 You can define relationships in a "code-first" model if they are not in the database. 如果关系不在数据库中,则可以在“代码优先”模型中定义它们。 The only condition is that foreign keys must refer to properties that EF knows as primary keys. 唯一的条件是外键必须引用EF称为主键的属性。 So you should be able to do LINQ queries using navigation properties in stead of these verbose joins by a model like this (reduced to the essentials): 因此,您应该能够使用导航属性来执行LINQ查询,而不是像这样的模型(简化为要点)来代替这些详细的联接:

class Human
{
    public int HumanId { get; set; }

    public int LastFoodEatenId { get; set; }
    public virtual Food LastEatenFood { get; set; }

    public int FavoriteFoodId { get; set; }
    public virtual Food FavoriteFood { get; set; }

    public int CurrentlyDesiredFoodId { get; set; }
    public virtual Food CurrentlyDesiredFood { get; set; }

    public virtual ICollection<Toy> Toys { get; set; }
    public virtual ICollection<Pet> Pets { get; set; }
}

class Food
{
    public int FoodId { get; set; }
}

class Pet
{
    public int PetId { get; set; }
    public int HumanOwnerId { get; set; }
}

class Toy
{
    public int ToyId { get; set; }
    public int HumanOwnerId { get; set; }
}

And a mapping: 和一个映射:

class HumanMapping : EntityTypeConfiguration<Human>
{
    public HumanMapping()
    {
        HasOptional(h => h.LastEatenFood).WithMany()
            .HasForeignKey(h => h.LastFoodEatenId);
        HasOptional(h => h.FavoriteFood).WithMany()
            .HasForeignKey(h => h.FavoriteFoodId);
        HasOptional(h => h.CurrentlyDesiredFood).WithMany()
            .HasForeignKey(h => h.CurrentlyDesiredFoodId);
        HasMany(h => h.Toys).WithOptional().HasForeignKey(t => t.HumanOwnerId);
        HasMany(h => h.Pets).WithOptional().HasForeignKey(t => t.HumanOwnerId);
    }
}

EF will infer the primary keys by name conventions. EF将按名称约定推断主键。

Now you will be able to execute a LINQ statement like: 现在,您将能够执行LINQ语句,例如:

context.Humans.Where(h => h.HumanId == id)
       .Include(h => h.LastEatenFood)
       .Include(h => h.FavoriteFood)
       .Include(h => h.CurrentlyDesiredFood)
       .Include(h => h.Toys)
       .Include(h => h.Pets)

From your description I understand that PetSurgery should be a junction class between Pet and another class ( Surgery ?). 从您的描述中我了解到PetSurgery应该是Pet和另一个类( Surgery ?)之间的PetSurgery类。 Anyway, I think you will manage creating the correct mappings, seeing this example. 无论如何,我认为您将看到此示例,将设法创建正确的映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM