包括 matchparticipants 不起作用。当我调试时它总是说 Null。 但是当我将 GroupBy 放在注释中时,它工作正常。我正在使用实体框架 4.3.1 和代码优先。
实体:
public class Match
{
[ScaffoldColumn(false)]
public int MatchId { get; set; }
[Required(ErrorMessage = "Matchtype is a required field")]
public int Scheme { get; set; }
[Required]
[DefaultValue(false)]
public bool Finished { get; set; }
public int Round { get; set; }
// Relations
[Required]
public Category Category { get; set; }
public Official Official { get; set; }
public Slot Slot { get; set; }
public ICollection<MatchParticipant> MatchParticipants { get; set; }
}
public class MatchParticipant
{
[ScaffoldColumn(false)]
public int MatchParticipantId { get; set; }
public int Points { get; set; }
public int Goals { get; set; }
[Required]
public Match Match { get; set; }
[Required]
public Team Team { get; set; }
}
public class Team
{
[ScaffoldColumn(false)]
public int TeamId { get; set; }
[Required(ErrorMessage="Name is a required field")]
public string Name { get; set; }
[Required(ErrorMessage="Number of players is a required field")]
public int NumberOfPlayers { get; set; }
[Required(ErrorMessage="Coach is a required field")]
public string Coach { get; set; }
[Required(ErrorMessage="Phone is a required field")]
public string Phone { get; set; }
public string CellPhone { get; set; }
public string Fax { get; set; }
[Required(ErrorMessage="Email is a required field")]
public string Email { get; set; }
[Required(ErrorMessage="Address is a required field")]
public Address Address { get; set; }
public Pool Pool { get; set; }
[Required(ErrorMessage = "Category is a required field")]
public Category Category { get; set; }
public ICollection<MatchParticipant> matchParticipants { get; set; }
}
var matches =
context.matches
.Include("Official")
.Include("Slot")
.Include("MatchParticipants.Team")
.Include("Category.Tournament")
.Where(m => m.Category.Tournament.TournamentId == tournamentId)
.GroupBy(m => m.Category);
如何使包含工作?
Include
要求查询的形状不改变。这意味着您的查询必须返回 IQueryable<Match>
。 GroupBy
运算符可能被视为形状改变,因为它返回 IQueryable<IGrouping<TKey, TSource>>
。一旦查询的形状发生变化,所有 Include 语句都将被省略。因此,您不能将 Include
与投影、自定义连接和分组一起使用。
作为解决方法,您可以在 Linq-to-objects 中执行分组:
var matches = context.matches
.Include("Official")
.Include("Slot")
.Include("MatchParticipants.Team")
.Include("Category.Tournament")
.Where(m => m.Category.Tournament.TournamentId == tournamentId)
.ToList()
.GroupBy(m => m.Category);
编辑: 正如评论和其他答案中提到的,这是非常危险的解决方法,可能会导致性能问题。它将所有记录从数据库提取到应用程序,并在应用程序中进行聚合。它可以在相同的情况下工作,但它绝对不适用于通用解决方案。
在这种特殊情况下,当您的 GroupBy 是最新的运算符时,此查询效果很好...但是恕我直言,上面的答案对于初学者来说是最糟糕的答案,因为当您的 GroupBy 未正确执行时,它会导致非常糟糕的优化查询在它之后,但后面跟着一些其他语句(Where、Select...)。
var ctx = new MyDataContext(); // Please use "using"
var result = ctx.SomeTable
//.Include(ah => ah.IncludedTable) // DO NOT PUT IT HERE
.Where(t => t.IsWhateverTrue)
.GroupBy(t => t.MyGroupingKey)
.Select(gt =>
gt.OrderByDescending(d => d.SomeProperty)
.FirstOrDefault(ah => ah.SomeAnotherFilter))
.Include(ah => ah.IncludedTable) // YES, PUT IT HERE
.ToList(); // Execute query here
GroupBy()
中指定包含内容。这会将它们包含在结果中:
var result = ctx.SomeTable
.Where(t => t.IsWhateverTrue)
.GroupBy(t => t.MyGroupingKey)
.Select(g => new
{
Date = g.Key.Value,
Reservations = g.Select(m => new
{
m,
m.IncludedTable // this selects/includes the related table
})
}
);
您可以在 GroupBy() 之后的 .Select() 中实现 Include,如下所示:var query = ctx.Table
.Where(x => "condition")
.GroupBy(g => g.GroupingKeyId)
.Select(x => new
{
GroupingKeyId = x.Key.GroupingKeyId,
GroupingKey = x.Select(y => y.GroupingKey)
.FirstOrDefault(y => y.Id == x.Key.GroupingKeyId)
});
我找不到在 SQL 端使用实体框架进行分组,然后在 .net 站点上使用 Include() 的工作方法。另一种方法是编写您自己的 SQL 查询并进行自己的映射。 这实际上并不难:
Install-Package dapper
定义要映射到的自定义对象(或使用现有对象)
class MyClass { int userID; int numRows;}
查询您的上下文对象:
List<MyClass> results = _context.Database.GetDbConnection().Query<MyClass>("SELECT u.id as userID, count(1) as numRows FROM Users u inner join Table2 t2 on u.id= t2.userID group by u.id;").ToList();