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
是DataAccess
类型List
的属性。我提到了x => x.id == id
部分,但this.schoolsList.Contains(x.school_id)
部分对我来说毫无意义。我知道x => x.id == id
返回与作为参数传入的id匹配的Team对象,但this.schoolsList.Contains(x.school_id)
究竟是如何工作的?我怎样才能使用school_id
属性(这是Team类的属性)?
谓词的第一部分(x => x.id == id
)是否返回Team对象,然后第二部分是使用返回对象的学校ID?出于某些原因,这似乎是一种奇怪的事情,因为我有点认为Where()
方法中的所有内容都会返回一些东西,而不是每个条件都返回一些东西。
答案 0 :(得分:2)
使用IN子句将contains方法转换为SQL。假设该列表包含3个项目1,2,3,则转换为
where team.school_id in (1,2,3)
看看生成的sql,例如intellisense会显示它,如果你有VS终极版,事情将变得可以理解。 否则请查看此How do I view the SQL generated by the Entity Framework?
我用自己的一个例子做了这个:
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'))
来自包含电话。
注意在应用于字符串时,包含的翻译方式有何不同。不是EF很棒; - )
答案 1 :(得分:2)
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
您可以通过Teams
ctx
Include
语句用于连接其他表,例如Join in SQL,并检索连接表中的数据。
.Where(x => x.id == id
&& this.schoolsList.Contains(x.school_id))
您在此处过滤表格数据,其中该行具有变量id
中的ID且位于schoolsList
内。
FirstOrDefault();
这将检索IQueryable
子句返回的Where
内的第一个项目。
这也可以翻译为:
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));
像这样写的包含更少的错误和更多的OOP。为此,您需要以下命名空间System.Data.Entity
。
**编辑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)
时,您在schoolsList
引起的每个“SQL迭代”上调用列表Where
。
就像在做:
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;
}
}
答案 2 :(得分:1)
。有人可以帮我理解以下内容吗?
它会多次调用Include()
方法,返回this
(同一个对象),因此它可以再次调用它。
然后它使用LINQ查询(似乎IEnumerable&lt;&gt;继承)在lambda中按条件查找特定元素。
FirstOrDefault()
会返回第一个匹配元素(如果有)或null
(default(T)
)。回答你的原始问题。
Lambda条件是if
项的简单IEnumerable
表达式。每次true
枚举内部数组以确定项是否匹配时,都会调用Lambda返回false
或FirstOrDefault()
。