[英]Entity framework with Linq to Entities performance
If I have a static method like this 如果我有这样的静态方法
private static bool TicArticleExists(string supplierIdent)
{
using (TicDatabaseEntities db = new TicDatabaseEntities())
{
if((from a in db.Articles where a.SupplierArticleID.Equals(supplierIdent) select a).Count() > 0)
return true;
}
return false;
}
and use this method in various places in foreach loops or just plain calling it numerous times, does it create and open new connection every time? 并在foreach循环的不同位置使用此方法,或者只是多次调用它,它是否每次都会创建并打开新的连接?
Thank you for clarification. 谢谢您的澄清。
new connections are non-expensive thanks to connection caching. 由于有了连接缓存,新的连接不昂贵。 Basically, it grabs an already open connection (I htink they are kept open for 2 minutes for reuse). 基本上,它抓住了一个已经打开的连接(我想它们会保持打开状态2分钟以备重用)。
Still, caching may be better. 不过,缓存可能会更好。 I do really not like the "firstordefault". 我真的不喜欢“ firstordefault”。 Thinks of whether you can acutally pull in more in ONE statement, then work from that. 考虑是否可以在ONE语句中手动添加更多内容,然后从中进行工作。
For the rest, I can not say anything - too much depends on what you actually do there logically. 对于其余的内容,我什么也不能说-太多取决于您在逻辑上实际执行的操作。 What IS TicDatabaseEntities? 什么是TicDatabaseEntities? CAN it be cached? 可以缓存吗? How long? 多久? Same with (3) - we do not know because we do not know what else is in there. 与(3)相同-我们不知道,因为我们不知道那里还有什么。
If this is something like getting just some lookup strings for later use, I would say.... 如果这就像只是获取一些查找字符串以供以后使用,我会说...。
Without business knowledge this can not be answered. 没有商业知识,这是无法回答的。
4: yes, that is as documented. 4:是的。 First gives first or an exception, FirstOrDefault defaults to default (empty struct initialized with 0, null for classes). 首先给出first或一个异常,FirstOrDefault默认为default(以0初始化的空结构,对于类为null)。
Thanks Dan and TomTom, I've came up with this. 感谢Dan和TomTom,我想出了这个。 Could you please comment this if you see anything out or the order? 如果您看到任何东西或订单,请对此发表评论?
public static IEnumerable<Article> TicArticles
{
get
{
ObjectCache cache = MemoryCache.Default;
if (cache["TicArticles"] == null)
{
CacheItemPolicy policy = new CacheItemPolicy();
using(TicDatabaseEntities db = new TicDatabaseEntities())
{
IEnumerable<Article> articles = (from a in db.Articles select a).ToList();
cache.Set("TicArticles", articles, policy);
}
}
return (IEnumerable<Article>)MemoryCache.Default["TicArticles"];
}
}
private static bool TicArticleExists(string supplierIdent)
{
if (TicArticles.Count(p => p.SupplierArticleID.Equals(supplierIdent)) > 0)
return true;
return false;
}
If this is ok, I'm going to make all my method follow this pattern. 如果可以,我将使我的所有方法都遵循此模式。
does it create and open new connection every time? 每次都会创建并打开新的连接吗?
No. Connections are cached. 否。连接已缓存。
Should I cache the results somewhere 我应该将结果缓存在某处吗
No. Do not cache entire tables. 不。不要缓存整个表。
should I make TicDatabaseEntities variable static and initialize it at class level? 我应该使TicDatabaseEntities变量为静态变量并在类级别对其进行初始化?
No. Do not retain a DataContext instance longer than a UnitOfWork. 不可以。DataContext实例的保留时间不能超过UnitOfWork。
Should my class be static if it contains only static methods? 如果我的类仅包含静态方法,它应该是静态的吗?
Sure... doing so will prevent anyone from creating useless instances of the class. 当然...这样做将防止任何人创建该类的无用实例。
Also I've noticed that if I return result.First() instead of FirstOrDefault() and the query does not find a match, it will issue an exception 另外我还注意到,如果我返回result.First()而不是FirstOrDefault()且查询未找到匹配项,它将发出异常
That is the behavior of First. 那就是第一的行为。 As such - I typically restrict use of First to IGroupings or to collections previously checked with .Any(). 因此,我通常将First的使用限制为IGroupings或以前使用.Any()检查的集合。
I'd rewrite your existing method as: 我会将您现有的方法重写为:
using (TicDatabaseEntities db = new TicDatabaseEntities())
{
bool result = db.Articles
.Any(a => a.supplierArticleID.Equals(supplierIdent));
return result;
}
If you are calling the method in a loop, I'd rewrite to: 如果您要循环调用该方法,我将重写为:
private static Dictionary<string, bool> TicArticleExists
(List<string> supplierIdents)
{
using (TicDatabaseEntities db = new TicDatabaseEntities())
{
HashSet<string> queryResult = new HashSet(db.Articles
.Where(a => supplierIdents.Contains(a.supplierArticleID))
.Select(a => a.supplierArticleID));
Dictionary<string, bool> result = supplierIdents
.ToDictionary(s => s, s => queryResult.Contains(s));
return result;
}
}
I'm trying to find the article where I read this, but I think it's better to do (if you're just looking for a count): 我正在尝试找到我读过的文章,但我认为最好这样做(如果您只是想找个数目):
from a in db.Articles where a.SupplierArticleID.Equals(supplierIdent) select 1
Also, use Any instead of Count > 0. 另外,请使用“任意”而不是“计数”> 0。
Will update when I can cite a source. 当我可以引用来源时会更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.