C# 如何实施";“自由形式”;实体框架中的关系6
我使用EF6来处理一个构造得有些粗糙的数据库。我使用的是代码优先模型 很多逻辑关系并没有使用键正确实现,而是使用了以前使用复杂SQL查询处理过的各种其他策略(例如,字符分隔的ID或字符串) (更改架构不是一个选项) 我真的想把这些关系作为属性来捕捉。可以通过使用显式查询而不是使用fluent/attribute语法定义实际关系来实现这一点 我计划通过使用执行查询的C# 如何实施";“自由形式”;实体框架中的关系6,c#,.net,entity-framework,C#,.net,Entity Framework,我使用EF6来处理一个构造得有些粗糙的数据库。我使用的是代码优先模型 很多逻辑关系并没有使用键正确实现,而是使用了以前使用复杂SQL查询处理过的各种其他策略(例如,字符分隔的ID或字符串) (更改架构不是一个选项) 我真的想把这些关系作为属性来捕捉。可以通过使用显式查询而不是使用fluent/attribute语法定义实际关系来实现这一点 我计划通过使用执行查询的IQueryable属性来实现这一点。例如: partial class Product { public IQueryabl
IQueryable
属性来实现这一点。例如:
partial class Product {
public IQueryable<tblCategory> SubCategories {
get {
//SubCategoriesID is a string like "1234, 12351, 12" containing a list of IDs.
var ids = SubCategoriesID.Split(',').Select(x => int.Parse(x.Trim()));
return from category in this.GetContext().tblCategories
where ids.Contains(category.CategoryID)
select category;
}
}
}
部分类积{
公共可查询子类别{
得到{
//SubCategoriesID是一个类似“1234、12351、12”的字符串,包含ID列表。
var id=SubCategoriesID.Split(',).Select(x=>int.Parse(x.Trim());
从此.GetContext().tblCategories中的类别返回
其中id.Contains(category.CategoryID)
选择类别;
}
}
}
(方法是一种扩展方法,它以某种方式获取了适当的DbContext
)
然而,有没有更好的方法来做到这一点,我不熟悉
此外,如果我这样做,那么为操作获取DbContext
的最佳方法是什么?它可以是:
首先,我建议不要返回IQueryable,因为它保留了与原始DbContext的关系。相反,我将
ToList
查询结果,并将其作为IEnumerable
尽量不要让DbContext
实例挂起;它们中有很多状态管理,而且由于它们不是线程安全的,所以您不希望多个线程访问同一个实例。我个人倾向于遵循的数据访问方法模式是在using块中使用新的DbContext
:
using (var ctx = new YourDbContextTypeHere()) {
return (from category in ctx.tblCategories
where ids.Contains(category.CategoryID)
select category).ToList();
}
首先,我建议不要返回IQueryable,因为它保留了与原始DbContext的关系。相反,我将
ToList
查询结果,并将其作为IEnumerable
尽量不要让DbContext
实例挂起;它们中有很多状态管理,而且由于它们不是线程安全的,所以您不希望多个线程访问同一个实例。我个人倾向于遵循的数据访问方法模式是在using块中使用新的DbContext
:
using (var ctx = new YourDbContextTypeHere()) {
return (from category in ctx.tblCategories
where ids.Contains(category.CategoryID)
select category).ToList();
}
请注意,ID列表中的.Contains()在EF中非常慢,也就是说,请尽量避免使用它。我会使用子查询,例如
var subcategories = context.SubCategories.Where(...);
var categories = context.Categories.Where(x => subCategories.Select(x => x.Id).Contains(category.CategoryId);
在此设置中,您可以避免将所有ID加载到服务器上,并且查询速度会很快。请注意,ID列表上的.Contains()在EF中非常慢,即尝试避免它。我会使用子查询,例如
var subcategories = context.SubCategories.Where(...);
var categories = context.Categories.Where(x => subCategories.Select(x => x.Id).Contains(category.CategoryId);
在这种设置中,您可以避免将所有ID加载到服务器上,查询速度也会很快。我看不出这段代码与问题或我的情况有什么关系。由于该列包含ID列表,因此我必须以某种方式处理它。我可以使用
String.Contains
,但我怀疑这会更慢。另外,您是否可以找出包含的非常慢的语句的来源?我想知道为什么。我认为它只会被映射到一个IN
类语句中。问题是EF不能用参数列表预编译任何东西。您是对的,SQL将在中生成,但是为EF解析表达式树的编译可能非常重要(比SQL查询本身的执行时间长)。每当EF无法预编译时,它的速度就非常慢……我不知道这段代码与问题或我的环境有什么关系。由于该列包含ID列表,因此我必须以某种方式处理它。我可以使用String.Contains
,但我怀疑这会更慢。另外,您是否可以找出包含的非常慢的语句的来源?我想知道为什么。我认为它只会被映射到一个IN
类语句中。问题是EF不能用参数列表预编译任何东西。您是对的,SQL将在中生成,但是为EF解析表达式树的编译可能非常重要(比SQL查询本身的执行时间长)。每当EF无法预编译时,它的速度就非常慢。。。