我有以下代码。
var category = Office.Categories.FirstOrDefault(c => c.Description == name);
Office
是之前读过的Framework Entity对象。
即使我的数据库使用不区分大小写的字符串比较,并且除了大小写之外,其中一个项目完全匹配,此代码返回null
。
我对这里发生的事情的理解是Office.Categories
返回所有相关的行,然后通过常规LINQ搜索这些行,这是区分大小写的。
如果是这样,那是非常低效的,因为我只想返回符合我条件的行。
有人能证实我对此的理解吗?是否可以强制过滤在SQL中进行,这样我就不需要返回我不感兴趣的行? (文本比较将不区分大小写?)
感谢您的帮助。
答案 0 :(得分:1)
如果你已经加载了Office
对象(也取决于延迟加载,但假设你不在上下文中)那么你基本上是在做一个区分大小写的linq-to-object查询。如果你想做linq-to-sql那么你应该采取不同的方式,例如:
context.Offices.FirstOrDefault(o=>o.OfficeId == someId)
.Categories.FirstOrDefault(c => c.Description == name);
或
context.Categories.FirstOrDefault(c => c.OfficeId == Office.OfficeId
&& c.Description == name);
答案 1 :(得分:1)
正确,所以你不能:
如果使用延迟加载,则调用Categories属性getter,因为这会导致EF从数据库中检索完整的类别列表
使用预先加载,因为这也会导致从数据库加载完整的类别列表
为避免这种情况,您可以使用以下代码(来自此答案:Using CreateSourceQuery in CTP4 Code First)
public ObjectQuery<T> CreateNavigationSourceQuery<T>(object entity, string navigationProperty)
{
var ose = this.ObjectContext.ObjectStateManager.GetObjectStateEntry(entity);
var rm = this.ObjectContext.ObjectStateManager.GetRelationshipManager(entity);
var entityType = (EntityType)ose.EntitySet.ElementType;
var navigation = entityType.NavigationProperties[navigationProperty];
var relatedEnd = rm.GetRelatedEnd(navigation.RelationshipType.FullName, navigation.ToEndMember.Name);
return ((dynamic)relatedEnd).CreateSourceQuery();
}
将它添加到您的上下文并调用它来创建一个ObjectQuery ..您可以在此调用FirstOrDefault,它不会从数据库中检索所有实体:
var category = context.CreateNavigationSourceQuery<Category>(Office, "Categories").FirstOrDefault(c => c.Description == name);