Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于两个关键变量访问对象的最有效的集合是什么?_C#_.net - Fatal编程技术网

C# 基于两个关键变量访问对象的最有效的集合是什么?

C# 基于两个关键变量访问对象的最有效的集合是什么?,c#,.net,C#,.net,我正在尝试实现一个大型对象缓存(高达500000个),需要能够以两种不同的方式访问它们 每个项目的键由三个不同的字符串组成;ItemNumber、PubCode和SizeCode。在某些情况下,我将调用所有三个值的匹配来返回单个对象。在其他情况下,我将仅调用ItemNumber和PubCode的匹配,以返回对象集合 最好的收藏是什么 我考虑过使用一个对象的通用列表(其中所有三个键值都是属性),并使用LINQ来查询它,但是我不认为这将是最有效的方式,尤其是在考虑集合的大小时。 我们将一如既往地感谢

我正在尝试实现一个大型对象缓存(高达500000个),需要能够以两种不同的方式访问它们

每个项目的键由三个不同的字符串组成;ItemNumber、PubCode和SizeCode。在某些情况下,我将调用所有三个值的匹配来返回单个对象。在其他情况下,我将仅调用ItemNumber和PubCode的匹配,以返回对象集合

最好的收藏是什么

我考虑过使用一个对象的通用列表(其中所有三个键值都是属性),并使用LINQ来查询它,但是我不认为这将是最有效的方式,尤其是在考虑集合的大小时。


我们将一如既往地感谢您的帮助

对于任何ItemNumber/PubCode组合,您可能有多少项?如果答案是“相当少”,那么我会从查找
开始(或者从
字典开始)
——因此,如果只要求他们两人查找,就可以直接找到所有匹配项。如果这三个函数都要求您查找,那么您可以非常快速地获取前两个函数的所有匹配项,然后按SizeCode对任何匹配项进行O(n)扫描

(此处
ItemNumberPubCode
是封装
ItemNumber
PubCode
的类型;它可以是匿名类型、
元组或实类型。)


如果一个特定的ItemNumber/PubCode组合可能有很多匹配项,那么您可能需要一个
字典
——它可以让您高效地通过这三个组合进行搜索,您可以从其中的两个中提取字典,并使用
属性查找该对的所有匹配值。

基本上,您可以使用树或哈希结构进行索引(例如(排序的)字典)-在您的情况下,您可以使用其中三个。 你只需要准确地确定你需要什么


我不知道您的情况,但我想只基于一个属性进行缓存就足够了,在其他情况下只使用普通的数据库索引(或多或少与上面相同)。

这里有一个使用字典字典的简单方法。就像乔恩说的,你是否需要这个取决于数据

class TwoKeyDictionary<T> : Dictionary<string, Dictionary<string, T>>
{
    public new IEnumerable<T> this[string key1]
    {
        get { return base[key1].Values; }
    }

    public T this[string key1, string key2]
    {
        get { return base[key1][key2]; }
    }

    public void Add(string key1, string key2, T item)
    {
        if (!base.ContainsKey(key1))
            base[key1] = new Dictionary<string, T>();
        base[key1].Add(key2, item);
    }
}
class TwoKeyDictionary:字典
{
public new IEnumerable this[string key1]
{
获取{返回基[key1].Values;}
}
public T this[string key1,string key2]
{
获取{返回基[key1][key2];}
}
公共无效添加(字符串键1、字符串键2、T项)
{
如果(!base.ContainsKey(键1))
base[key1]=新字典();
基[key1]。添加(key2,项);
}
}

由于它是只读的,我将创建一个包含两个集合的非集合类

public class CacheOfManyObjects
{
    private Dictionary<string, ObjectsToBeCached> ObjectsByItemPubSize{get;set;}
    //You might want to replace the IEnumerable<> with a List<>
    // but that depends on implementation
    private Dictionary<string, IEnumerable<ObjectsToBeCached>> ObjectsByItemPub{get;set;}

    public ObjectsToBeCached GetByItemPubSize(string tString);
    public IEnumerable<ObjectsToBeCached> GetByItemPub(string tString);
}
多对象的公共类缓存
{
私有字典对象sbyitempubize{get;set;}
//您可能希望用列表替换IEnumerable
//但这取决于实施情况
私有字典对象sbyitempub{get;set;}
public ObjectsToBeCached GetByItemPubSize(string tString);
公共IEnumerable GetByItemPub(字符串tString);
}

对象将被添加到每个字典中。您需要额外的逻辑来创建对象缓存,但没有真正的理由只有一个集合,因为集合本身很小。

现有的缓存解决方案都不能满足您的需要?这是只读的还是您希望在运行时将项添加到此数据结构?抱歉,缓存将是只读的。它大约每5分钟刷新一次。我担心您必须编写自己的集合,并像@Philips的回答中那样管理添加和删除操作。我认为词典似乎是正确的方法,尽管我对您使用元组很感兴趣。。。就只读性能而言,当用作字典键时,与连接的字符串相比,它的性能如何?@JamesLaw:老实说,我不想猜测,但是连接的字符串有一个问题,因为{“Foo”,“Bar”}最终与{“FooB”,“ar”}具有相同的键。当然,如果您知道分隔符不会出现在键中,您可以自己添加分隔符。您可能需要考虑一个具有两个字符串引用的自定义结构作为键类型(当然,重写等值/GethAc码)。和往常一样,基准是用来确定实际成本的。