简体   繁体   English

EF 6 和 SQL 到 LINQ?

[英]EF 6 and SQL to LINQ?

I'm trying to convert my SQL statement into .NET Core 6 C# syntax rather than using .FromSqlRaw.我正在尝试将我的 SQL 语句转换为 .NET Core 6 C# 语法,而不是使用 .FromSqlRaw。

I've review LINQ doc but the don't seem to cover the join scenario I need and the documentation doesn't actually describe the process.我已经查看了 LINQ 文档,但似乎没有涵盖我需要的连接场景,并且文档实际上并没有描述该过程。

SELECT        dbo.TRIGGERS.trgID, dbo.TRIGGERS.atvID, dbo.TRIGGERS.trgEvent, dbo.TRIGGERS.trgIsDeleted
FROM            dbo.CLIENTFACILITYTRIGGERS INNER JOIN
                         dbo.TRIGGERS ON dbo.CLIENTFACILITYTRIGGERS.trgID = dbo.TRIGGERS.trgID
WHERE        (dbo.CLIENTFACILITYTRIGGERS.cltID = 1) AND (dbo.CLIENTFACILITYTRIGGERS.facID = 1)

CLIENTFACILITYTRIGGERS is a table with composite key on it's 3 field cltID facID trgID CLIENTFACILITYTRIGGERS 是一个带有复合键的表,它的 3 个字段 cltID facID trgID

TRIGGERS has a single primary key (trgID) trgID atvID trgEvent trgIsDeleted TRIGGERS 有一个主键 (trgID) trgID atvID trgEvent trgIsDeleted

Simple query, get all TRIGGERS for a given cltId and facID.简单查询,获取给定 cltId 和 facID 的所有 TRIGGERS。

I'm not having much luck converting this to .NET 6 Core C# LINQ.我没有太多运气将它转换为 .NET 6 Core C# LINQ。 Or, point me to a good resource (not Microsoft's documentation and not automatic converters) that explain how to convert SQL into .NET 6 Core C# LINQ?或者,向我指出一个很好的资源(不是 Microsoft 的文档,也不是自动转换器),它解释了如何将 SQL 转换为 .NET 6 Core C# LINQ? I want to learn, not mimic.我想学习,而不是模仿。

You don't need JOINs if your classes have proper relations.如果您的类具有适当的关系,则不需要 JOIN。 ORMs like Entity Framework allow you to work with classes, not tables.像实体框架这样的 ORM 允许您使用类,而不是表。 If you have a ClientFacility class with a Triggers collection, EF itself will generate the proper JOINs when you load a ClientFacility .如果您有一个带有Triggers集合的ClientFacility类,EF 本身将在您加载ClientFacility时生成正确的 JOIN。

TheRelationships article in the EF Core documentation shows how to define relationships in general so you don't have to deal with keys and JOINs in queries. EF Core 文档中的关系文章展示了如何定义一般关系,因此您不必处理查询中的键和 JOIN。

The Blog/Posts example shows how to handle 1:M relations:博客/帖子示例展示了如何处理 1:M 关系:

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public string Title {get;set;}
    
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

With these classes, if you want to find all the posts of a blog you can write :使用这些类,如果您想查找博客的所有帖子,您可以编写:

var posts=_context.Posts.Where(p=>p.Blog.Title="Bananas");

It's EF's job to generate the Blogs INNER JOIN Posts ON Blogs.BlogID=Posts.BlogId clause.生成Blogs INNER JOIN Posts ON Blogs.BlogID=Posts.BlogId子句是 EF 的工作。

In the question's case it seems there's a many-to-many relation between ClientFacility and Trigger .在问题的情况下, ClientFacilityTrigger之间似乎存在多对多的关系。 EF Core 6 allows modelling many-to-many relations without also modelling the bridge class ClientFacilityTrigger . EF Core 6 允许对多对多关系进行建模,而无需对桥接类ClientFacilityTrigger进行建模。

Assuming you have :假设你有:

public class ClientFacility
{
    public long ClientFacilityId {get;set;}

    public List<Trigger> Triggers {get;set}
}

public class Trigger
{
   public long TriggerId {get;set;}

   public string Event {get;set;}
   public bool IsDeleted {get;set;}
}

public class MyContext:DbContext
{
    public DbSet<Facility> Facilities {get;set;}
    public DbSet<Trigger> Triggers {get;set;}
}

You could retrieve a facility's triggers with :您可以使用以下命令检索设施的触发器:

var results=from facility in _context.Facilities
            where facility.ClientFacilityId=1
            from trigger in facility.Triggers
            select new {
                trigger.Event,
                trigger.IsDeleted,
                ...
            };

A DbContext's OnModelBuilding method can be used to define more complex relations, eg using composite keys or columns that don't follow naming conventions. DbContext 的OnModelBuilding方法可用于定义更复杂的关系,例如使用不遵循命名约定的复合键或列。

This clause makes me suspect there are more entities, Client and Facility and ClientFacility links them to Trigger .这个子句让我怀疑有更多的实体, ClientFacilityClientFacility将它们链接到Trigger This can be modelled as well :这也可以建模:

public class Client
{
    public long ClientId {get;set;}

    public List<ClientFacility> Facilities {get;set;}
}

public class Facility
{
    public long FacilityId {get;set;}

    public List<ClientFacility> Facilities {get;set;}
}

public class ClientFacility
{
    public long ClientFacilityId {get;set;}

    public long ClientId {get;set;}
    public long FacilityId {get;set;}

    public Client Client{get;set;}
    public Facility Facility {get;set;}
}

This should work for you, just use your context and the entities related to your tables (change this: context.CLIENTFACILITYTRIGGERS and this: context.TRIGGERS )这应该对您有用,只需使用您的上下文和与您的表相关的实体(更改此: context.CLIENTFACILITYTRIGGERS和此: context.TRIGGERS

var query = 
    from cft in context.CLIENTFACILITYTRIGGERS 
    join t in context.TRIGGERS on cft.trgID equals t.trgID
    where cft.cltID == 1 && cft.facID == 1
    select new 
    {
        TrgId = t.trgID, 
        AtvId = t.atvID, 
        TrgEvent = t.trgEvent, 
        TrgIsDeleted = t.trgIsDeleted
    };

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

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