有人可以帮我理解以下内容吗?

时间:2015-07-22 16:38:31

标签: c# asp.net-mvc model-view-controller

    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();

          ///

       }

ctxDataAccess对象,schoolsListDataAccess类型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()方法中的所有内容都会返回一些东西,而不是每个条件都返回一些东西。

3 个答案:

答案 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()会返回第一个匹配元素(如果有)或nulldefault(T))。回答你的原始问题。

Lambda条件是if项的简单IEnumerable表达式。每次true枚举内部数组以确定项是否匹配时,都会调用Lambda返回falseFirstOrDefault()