我已经在EF上使用LinQ to SQL一段时间了,并且偶然发现了一些奇怪的行为,希望有人可以为我解释。
我正在对数据库上下文执行LinQ查询,该数据库上下文具有POCO实体,该实体具有相关实体的虚拟属性。我正在使用where子句来消除该实体为null的实例。我正在使用Lazy Loading。
return this.runtimeContext.FatalExceptionLogs.Where(l => l.RuntimeToDesignJuicerRelationship != null);
我发现,当我的查询被评估时,LinQ to SQL似乎完全忽略了我的条件,即虚拟属性为null,就好像我根本没有包含此检查一样。相反,它返回名为FatalExceptionLogs的dbset中的所有记录。
现在我有一个简单的解决方法,首先使用.ToList()然后将数据加载到内存中
看起来像这样:
return this.runtimeContext.FatalExceptionLogs.ToList().Where(l => l.RuntimeToDesignJuicerRelationship != null);
现在检查在内存中执行,并且返回虚拟属性为null的所有实例(因为没有相应的记录,因为用于连接的id是可空的)并且我们都很好。
我也考虑过:
检查所连接的id是否为null但不幸的是我无法保证表的参照完整性已被维护,因为没有应用外键的urgh!。
检查另一个表中是否有匹配id的记录,但这可能效率很低。
所以我有办法解决这个问题,但我真的很想理解为什么LinQ to Sql正在做这个以及有什么其他选择,有人可以帮忙吗?
如果有帮助的完整代码在下面,虽然我已经为此示例减少了它:
查询:
return this.runtimeContext.FatalExceptionLogs.ToList().Where(l => l.RuntimeToDesignJuicerRelationship != null);
实体:
public class FatalExceptionLog
{
public int Id { get; set; }
public int? RuntimeJuicerId { get; set; }
public virtual RuntimeToDesignJuicerRelationship RuntimeToDesignJuicerRelationship { get; set; }
}
映射:
public class FatalExceptionLogMap : EntityTypeConfiguration<FatalExceptionLog>
{
public FatalExceptionLogMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Table & Column Mappings
this.ToTable("FatalExceptionLogging");
this.Property(t => t.RuntimeJuicerId).HasColumnName("JuicerLiveID");
this.HasRequired(t => t.RuntimeToDesignJuicerRelationship)
.WithMany(t => t.FatalExceptionLogs)
.HasForeignKey(t => t.RuntimeJuicerId);
}
}
答案 0 :(得分:1)
为什么不只是正常加入?
return this.runtimeContext.FatalExceptionLogs.Where(
l => runtimeContext.RuntimeJuicers.Any(
y => y.RuntimeJuicerId == l.RuntimeJuicerId
)
);