有人能帮我理解下面这句话吗?
本文关键字:这句话 | 更新日期: 2023-09-27 18:04:17
public Team getTeamByID(int id)
{
Team team = ctx.Teams.Include("Login").Include("People").Include("School").Where(x => x.id == id && this.schoolsList.Contains(x.school_id)).FirstOrDefault();
///
}
ctx
是DataAccess
对象,schoolsList
是List
类型的DataAccess
属性。我理解x => x.id == id
的部分,但this.schoolsList.Contains(x.school_id)
的部分对我来说没有意义。我知道x => x.id == id
返回的团队对象与作为参数传入的id相匹配,但this.schoolsList.Contains(x.school_id)
究竟是如何工作的?我怎么能使用school_id
属性(这是团队类的属性)?
谓词的第一部分(x => x.id == id
)是否返回Team Object,然后第二部分使用返回对象的学校id?由于某种原因,这似乎是一种奇怪的方式,因为我有点认为Where()
方法中的所有内容都返回了一些东西,而不是每个条件返回一些东西。
Team team = ctx.Teams
.Include("Login")
.Include("People")
.Include("School")
.Where(x => x.id == id
&& this.schoolsList.Contains(x.school_id))
.FirstOrDefault();
在这一行中,您将检索ctx.Teams
中满足Where
子句
ctx.Teams
这里通过ctx
从数据库调用表Teams
Include
语句用于连接其他表,如SQL中的join,并检索连接表中的数据。
.Where(x => x.id == id
&& this.schoolsList.Contains(x.school_id))
在这里,您正在过滤表数据,其中行具有来自变量id
的id,并且位于schoolsList
内。
FirstOrDefault();
:检索Where
子句返回的IQueryable
中的第一项。
这也可以翻译成:
Team team = ctx.Teams
.Include(x => x.Login)
.Include(x => x.People)
.Include(x => x.School)
.FirstOrDefault(x => x.id == id
&& this.schoolsList.Contains(x.school_id));
像这样编写的包含更少bug,更面向对象。为此,您需要以下命名空间System.Data.Entity
。
** EDIT 1 **
我有点理解,但不是完全理解。它怎么知道什么x.school_id吗?我以为我的问题里包含了这个,但我只是编辑后,传入该函数的唯一参数是"id"。那么,x.school_id的值究竟在哪里传递包含来自哪里?它是否来自返回的Team对象条件x.id == id?——FrostyStraw
因为Where
子句或FirstOrDefault
通过ctx.Teams
对SQL进行迭代,其中Teams
的类包含属性school_id
。
这只能在EntityFramework中实现,其中表由类表示,类属性是表列。
啊!当你执行this.schoolsList.Contains(x.school_id)
时,你在每次由Where
引起的"SQL迭代"上调用列表schoolsList
。
就像这样做:
List<Team> teams = ctx.Teams
.Include("Login")
.Include("People")
.Include("School")
.ToList();
Team team = null;
foreach (var item in teams)
{
if (item.id == id && this.schoolsList.Contains(item.school_id))
{
team = item;
break;
}
}
contains方法通过IN子句转换为SQL。假设列表包含3项1,2,3,那么它被翻译成
where team.school_id in (1,2,3)
看一下生成的sql,例如智能感知显示它,如果你有VS ultimate,事情就会变得容易理解。否则看看这个我如何查看由实体框架生成的SQL ?
我已经用我自己的一个例子做了这件事:
string[] roles = {"admin","medewerker"};
_medewerkers = contactPersoonRepository
.Query(c => c.Bedrijf.BEDRIJF_TYPE.Contains("P") && roles.Contains(c.CP_ROLE))
.NoTracking()
.OrderBy(q => q.OrderBy(d => d.CP_NAAM))
.Select(b => new Medewerker
{
Naam = b.CP_NAAM,
VoorNaam = b.CP_VOORNM,
Id = b.CP_CPID,
Rol = b.CP_ROLE,
Uurloon = b.CP_UURLOON
}).ToList();
转化为
USE [Jogical];
GO
SELECT
[Extent1].[CP_CPID] AS [CP_CPID],
[Extent1].[CP_NAAM] AS [CP_NAAM],
[Extent1].[CP_VOORNM] AS [CP_VOORNM],
[Extent1].[CP_ROLE] AS [CP_ROLE],
[Extent1].[CP_UURLOON] AS [CP_UURLOON]
FROM [dbo].[ContactPersoon] AS [Extent1]
INNER JOIN [dbo].[Bedrijf] AS [Extent2] ON [Extent1].[CP_BEDRIJFID] = [Extent2].[BEDRIJF_ID]
WHERE ([Extent2].[BEDRIJF_TYPE] LIKE N'%P%') AND ([Extent1].[CP_ROLE] IN (N'admin', N'medewerker')) AND ([Extent1].[CP_ROLE] IS NOT NULL)
ORDER BY [Extent1].[CP_NAAM] ASC
相关部分如下:
([Extent1].[CP_ROLE] IN (N'admin', N'medewerker'))
来自contains调用。
请注意,当应用于字符串时,contains的翻译是不同的。-)
。有人能帮我理解下面这句话吗?
它多次调用Include()
方法,返回this
(相同的对象),所以它可以再次调用它。
然后使用LINQ查询(似乎IEnumerable<> inherited)根据lambda中的条件查找特定元素。
FirstOrDefault()
返回第一个匹配元素(如果有的话)或null
(default(T)
)。回答你最初的问题。
Lambda条件是IEnumerable
项的简单if
表达式。每次调用Lambda返回true
或false
时,FirstOrDefault()
将枚举内部数组以确定项是否匹配。