C# 基于双字段查找的数据库实体高效缓存策略

C# 基于双字段查找的数据库实体高效缓存策略,c#,performance,entity-framework,caching,C#,Performance,Entity Framework,Caching,为了优化某些DB实体的处理,我实现了一个非常简单的查找缓存。缓存类如下所示: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SyncEngine.Caches { class TenantsCache : Cache { System.Collections.G

为了优化某些DB实体的处理,我实现了一个非常简单的查找缓存。缓存类如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SyncEngine.Caches
{
    class TenantsCache : Cache
    {
       System.Collections.Generic.List<tenant> list;

        public override void ReadFromDB()
        {
            using (var ctx = new MyContext())
            {
                this.list = ctx.tenants.ToList<tenant>();
            }
        }

        public override void Add(object o)
        {
            list.Add((tenant)o);
        }

        public tenant LookupByFNandGID(string fn, int groupId)
        {
            tenant match = null;
            foreach (tenant t in list)
            {
                if (t.friendlyName == fn && t.groupId == groupId) // <-- slowest line
                {
                    match = t;
                    break;
                }
            }
            return match;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
命名空间SyncEngine.Caches
{
类租户缓存:缓存
{
System.Collections.Generic.List列表;
公共重写void ReadFromDB()
{
使用(var ctx=new MyContext())
{
this.list=ctx.tenants.ToList();
}
}
公共覆盖无效添加(对象o)
{
列表。添加((承租人)o);
}
公共租户lookupbynandgid(字符串fn,int-groupId)
{
租户匹配=null;
foreach(列表中的租户t)
{

如果(t.friendlyName==fn&&t.groupId==groupId)/您可以使用包含两个字段的自定义键创建字典:

class Key : IEquatable<Key>
{
    public string fn;
    public int groupId;

    public override bool Equals(object obj)
    {
        Key k = obj as Key;
        if (k == null)
        {
            return false;
        }
        else
        {
            return this.Equals(k);
        }
    }

    public bool Equals(Key other)
    {
        return this.fn == other.fn && this.groupId == other.groupId;
    }

    public override int GetHashCode()
    {
        return fn.GetHashCode() * 13 + groupId.GetHashCode();
    }
}
类密钥:IEquatable
{
公共字符串fn;
公共int-groupId;
公共覆盖布尔等于(对象对象对象)
{
键k=作为键的obj;
if(k==null)
{
返回false;
}
其他的
{
返回该值。等于(k);
}
}
公共布尔等于(关键其他)
{
返回this.fn==other.fn&&this.groupId==other.groupId;
}
公共覆盖int GetHashCode()
{
返回fn.GetHashCode()*13+groupId.GetHashCode();
}
}
然后,您可以使用比列表查找快得多的词典:

Dictionary<Key, tenant> foo = new Dictionary<Key, tenant>();
Dictionary foo=newdictionary();

您可以使用包含以下两个字段的自定义键创建字典:

class Key : IEquatable<Key>
{
    public string fn;
    public int groupId;

    public override bool Equals(object obj)
    {
        Key k = obj as Key;
        if (k == null)
        {
            return false;
        }
        else
        {
            return this.Equals(k);
        }
    }

    public bool Equals(Key other)
    {
        return this.fn == other.fn && this.groupId == other.groupId;
    }

    public override int GetHashCode()
    {
        return fn.GetHashCode() * 13 + groupId.GetHashCode();
    }
}
类密钥:IEquatable
{
公共字符串fn;
公共int-groupId;
公共覆盖布尔等于(对象对象对象)
{
键k=作为键的obj;
if(k==null)
{
返回false;
}
其他的
{
返回该值。等于(k);
}
}
公共布尔等于(关键其他)
{
返回this.fn==other.fn&&this.groupId==other.groupId;
}
公共覆盖int GetHashCode()
{
返回fn.GetHashCode()*13+groupId.GetHashCode();
}
}
然后,您可以使用比列表查找快得多的词典:

Dictionary<Key, tenant> foo = new Dictionary<Key, tenant>();
Dictionary foo=newdictionary();

如果您想在数据库级别上解决这个问题(您应该这样做),分布式数据库就是您要寻找的droid。许多进程中的数据库可以作为本地缓存数据库,以防性能出现问题或与主数据库的连接不可靠(移动应用程序)。对于SQL,它将是SQL Express。但是,当您提出有关速度的问题时,我觉得有必要将“速度咆哮”链接起来:特别是第2部分和第4部分对您的情况很重要。谢谢,但我确实需要回答这个问题,在我有东西可比较之前,我不知道这个差异是否相关。如果您想在DB lev上解决这个问题el(您应该这样做),分布式数据库是您正在寻找的droid。许多进程内数据库可以在性能不佳或与主数据库的连接不可靠的情况下(移动应用程序)充当本地缓存数据库。对于SQL,它将是SQL Express。然而,当你提出有关速度的问题时,我觉得有必要将“速度咆哮”链接起来:特别是第2部分和第4部分对你的情况很重要。谢谢,但我确实需要回答这个问题,在我有东西可以比较之前,我不知道这个差异是否相关。考虑到
Equals
与我之前所做的比较相同,字典查找真的会更高效吗?字典请求将在O(1)之后执行,同时foreach-O(N)。字典首先使用GetHashCode在它保存的内部哈希表中查找一个bucket。一旦它缩小到一个bucket,它就会在bucket中使用Equals来查找您要查找的条目。这意味着即使对于包含数百万项的字典,它也只调用Equals几次。假定
的实现等于ode>与我已经做的比较相同,字典查找真的会更有效吗?字典请求将在O(1)之后执行,同时foreach-O(N)。字典首先使用GetHashCode在它保存的内部哈希表中查找一个bucket。一旦它缩小到一个bucket,它将使用bucket中的Equals来查找您要查找的条目。这意味着即使对于包含数百万项的字典,它也只调用Equals几次。