【发布时间】:2014-09-17 19:48:42
【问题描述】:
我有点做噩梦,想弄清楚为什么以下Include(...) 后跟Where(...) 的组合没有产生预期的结果:
- 我通过
Where(...)将数据库中的项目分成两部分。 -
Where(...)条件是相互排斥和互补的。 -
Where(...)调用依赖于相关对象,因此我使用Include(...) - 我知道这两个部分都包含元素。
代码:
using (var db = new FeedDbContext("My-Database-Connection"))
{
var queryWithout = db.FeedEntries
.Include(f => f.MetadataFile)
.Where(f => f.MetadataFile == null);
var queryWith = db.FeedEntries
.Include(f => f.MetadataFile)
.Where(f => f.MetadataFile != null);
//-- using ToList().Count
var totalCount = db.FeedEntries.ToList().Count;
var countWithout = queryWithout.ToList().Count;
var countWith = queryWith.ToList().Count;
Console.WriteLine("totalCount using ToList().Count: {0}", totalCount);
Console.WriteLine("countWithout using ToList().Count: {0}", countWithout);
Console.WriteLine("countWith using ToList().Count: {0}", countWith);
//-- using Count()
totalCount = db.FeedEntries.Count();
countWithout = queryWithout.Count();
countWith = queryWith.Count();
Console.WriteLine("totalCount using Count(): {0}", totalCount);
Console.WriteLine("countWithout using Count(): {0}", countWithout);
Console.WriteLine("countWith using Count(): {0}", countWith);
//-- using CountAsync()
totalCount = await db.FeedEntries.CountAsync();
countWithout = await queryWithout.CountAsync();
countWith = await queryWith.CountAsync();
Console.WriteLine("totalCount using CountAsync(): {0}", totalCount);
Console.WriteLine("countWithout using CountAsync(): {0}", countWithout);
Console.WriteLine("countWith using CountAsync(): {0}", countWith);
}
打印的输出是:
totalCount using ToList().Count: 8372
countWithout using ToList().Count: 8372
countWith using ToList().Count: 0
totalCount using Count(): 8372
countWithout using Count(): 8372
countWith using Count(): 7908
totalCount using CountAsync(): 8372
countWithout using CountAsync(): 8372
countWith using CountAsync(): 7908
totalCount除外:
在这两种情况下,使用
ToList().Count的部分查询的计数都是错误的。-
IQueryable<T>扩展方法(CountAsync()来自EntityFramework和Count()来自System.Core)在两种情况下产生相同的结果。带有
MetadataFile的项目数正确没有
MetadataFile的项目计数不正确
没有
MetadataFile的项目数应等于 8372 - 7908 = 464,已在数据库中验证。
这表明我调用Include() 扩展方法的方式有问题。
这是因为我枚举多次相同的查询并且我保持相同的连接吗?
幕后是否有一些我不知道的奇怪性质并解释了这种看似奇怪的行为???
请多指教!!!
EF 型号详情
这就是我定义实体和映射的方式:
public partial class FeedEntry
{
public int Id { get; set; }
...
public virtual MetadataFile MetadataFile { get; set; }
public virtual ICollection<ImageFile> ImageFiles { get; set; }
public virtual ICollection<VideoFile> VideoFiles { get; set; }
...
}
public partial class MetadataFile : FileBase
{
...
public virtual FeedEntry FeedEntry { get; set; }
...
}
和映射:
modelBuilder.Entity<FeedEntry>()
.HasOptional(t => t.MetadataFile)
.WithRequired(t => t.FeedEntry);
modelBuilder.Entity<FeedEntry>()
.HasMany(t => t.ImageFiles)
.WithRequired(t => t.FeedEntry);
modelBuilder.Entity<FeedEntry>()
.HasMany(t => t.VideoFiles)
.WithRequired(t => t.FeedEntry);
特别是,这具有定义Optional:Required 关系的效果
FeedEntry 1 ←—→ 0..1 MetadataFile
其中FeedEntry 自动成为关系中的主体,MetadataFile 自动成为依赖关系。
所以问题已经得到解答,所有的解释都如answer below 所描述的那样,并且我使用所描述的模型来针对新数据库和现有数据库这一事实。
【问题讨论】:
-
你能告诉我们你是如何在 FeedEntry 类中声明 MetadataFile 的吗?
-
刚刚更新了 EF 映射信息...谢谢
-
你用的是什么版本的EF?
-
来自 NuGet 的实体框架 6.1.1
标签: c# linq entity-framework extension-methods iqueryable