简体   繁体   English

具有Linq to Entities性能的实体框架

[英]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循环的不同位置使用此方法,或者只是多次调用它,它是否每次都会创建并打开新的连接?

  1. If so, how can I tackle this? 如果是这样,我该如何解决? Should I cache the results somewhere, like in this case, I would cache the entire Classifications table in Memory Cache? 我是否应该将结果缓存在某个地方,例如在这种情况下,将整个分类表缓存在“内存缓存”中? And then do queries vs this cached object? 然后对这个缓存的对象进行查询吗?
  2. Or should I make TicDatabaseEntities variable static and initialize it at class level? 还是应该使TicDatabaseEntities变量为静态变量并在类级别将其初始化?
  3. Should my class be static if it contains only static methods? 如果我的类仅包含静态方法,它应该是静态的吗? Because right now it is not.. 因为现在不是。
  4. 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 (with FirstOrDefault() there is no exception, it returns null). 另外我还注意到,如果我返回result.First()而不是FirstOrDefault(),并且查询未找到匹配项,它将发出异常(对于FirstOrDefault()没有异常,它将返回null)。

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.... 如果这就像只是获取一些查找字符串以供以后使用,我会说...。

  • Build a key out of classI, class II, class III 从I级,II级,III级构建密钥
  • load all classifications in (I assume there are only a couple of hundred) 加载所有分类(我假设只有几百个)
  • Put them into a static / cached dictionary, assuming they normally do not change (and I htink I have that idea here - is this a financial tickstream database?) 假设它们通常不会更改,请将它们放入静态/缓存的字典中(我想我在这里有这个想法-这是财务滴答数据库吗?)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM