using System.Collections.Generic;
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public override string ToString()
return string.Format("{0} {1}, age {2}", FirstName, LastName, Age);
private static Random _random = new Random((int)DateTime.Now.Ticks);
private static string[] _firstNames = new string[]
private static string[] _lastNames = new string[]
public IEnumerable<DbEntity> GetSequence(int count)
for (int i = 0; i < count; i++)
yield return new DbEntity
FirstName = _firstNames[_random.Next(_firstNames.Length - 1)],
LastName = _lastNames[_random.Next(_lastNames.Length - 1)],
Age = _random.Next(18, 60)
public struct FirstLastKey
private readonly string _firstName;
private readonly string _lastName;
public FirstLastKey(string firstName, string lastName)
public override bool Equals(object obj)
if (obj == null) return false;
if (!(obj is FirstLastKey)) return false;
FirstLastKey otherValue = (FirstLastKey)obj;
return _firstName.Equals(otherValue._firstName) && (_lastName.Equals(otherValue._lastName));
public override int GetHashCode()
return _firstName.GetHashCode() ^ _lastName.GetHashCode();
public readonly int _age;
public override bool Equals(object obj)
if (obj == null) return false;
if (!(obj is AgeKey)) return false;
AgeKey otherValue = (AgeKey)obj;
return _age == otherValue._age;
public override int GetHashCode()
return _age.GetHashCode();
private readonly List<DbEntity> _entities = new List<DbEntity>();
private readonly Dictionary<FirstLastKey, List<DbEntity>> _fnDict = new Dictionary<FirstLastKey, List<DbEntity>>();
private readonly Dictionary<AgeKey, List<DbEntity>> _ageDict = new Dictionary<AgeKey, List<DbEntity>>();
public void AddRange(IEnumerable<DbEntity> entities)
_entities.AddRange(entities);
foreach (var entity in entities)
FirstLastKey fnKey = new FirstLastKey(entity.FirstName, entity.LastName);
if (_fnDict.ContainsKey(fnKey))
_fnDict[fnKey].Add(entity);
_fnDict[fnKey] = new List<DbEntity>() { entity };
AgeKey ageKey = new AgeKey(entity.Age);
if (_ageDict.ContainsKey(ageKey))
_ageDict[ageKey].Add(entity);
_ageDict[ageKey] = new List<DbEntity>() { entity };
public IList<DbEntity> FindBy(string firstName, string lastName)
FirstLastKey key = new FirstLastKey(firstName, lastName);
if (_fnDict.TryGetValue(key, out result))
return new DbEntity[] { };
public IList<DbEntity> FindBy(int age)
AgeKey key = new AgeKey(age);
if (_ageDict.TryGetValue(key, out result))
return new DbEntity[] { };
public static void Main()
var dbGenerator = new DbGenerator();
db.AddRange(dbGenerator.GetSequence(10000));
var items = db.FindBy("Jack", "Jones");
Console.WriteLine(items.Count);
var items2 = db.FindBy(30);
Console.WriteLine(items2.Count);