KeyInfo GetKey() { if (this.ApiFilter != null) { var keys = Resource.GetRecordInfo(typeof(TRecord)).Keys; var maxKeySegmentCount = keys.Max(k => k.Segments.Count); IEnumerable <KeyInfo> enabledKeys = keys, remainedKeys = new KeyInfo[0]; var enabledKeyList = new List <KeyInfo>(); var priorityList = new List <uint>(); var fields = this.ApiFilter .SelectMany(filter => filter.GetFields().Select(field => new { State = filter.State, Field = field })) .GroupBy(f => f.Field) .Select(g => new { Field = g.Key, Priority = GetPriority(g.Select(f => f.State)) }); for (var i = 0; i < maxKeySegmentCount; i++) { uint priority = 0; foreach (var key in enabledKeys) { var field = fields.SingleOrDefault(f => f.Field == key.Segments[i].Field); if (field != null) { if (field.Priority == priority) { enabledKeyList.Add(key); } else if (field.Priority > priority) { priority = field.Priority; enabledKeyList.Clear(); enabledKeyList.Add(key); } } } if (enabledKeyList.Count == 0) { if (remainedKeys.Count() == 0) { remainedKeys = enabledKeys.Where(k => i == k.Segments.Count - 1).ToArray(); } enabledKeys = enabledKeys.Where(k => i != k.Segments.Count - 1).ToArray(); } else if (enabledKeyList.Count == 1) { return(enabledKeyList[0]); } else if (enabledKeyList.Count > 1) { enabledKeys = enabledKeyList.Where(k => i != k.Segments.Count - 1).ToArray(); remainedKeys = enabledKeyList.Where(k => i == k.Segments.Count - 1).ToArray(); } enabledKeyList.Clear(); priorityList.Add(priority); } if (priorityList.Any(p => p != 0)) { return(remainedKeys.FirstOrDefault() ?? enabledKeys.FirstOrDefault()); } else { return(null); } } return(null); }
internal RecordInfo(Type recordType) { if (recordType.BaseType.GetGenericTypeDefinition() != typeof(Record <>)) { throw new InvalidDefinitionException(); } var classAttributes = recordType.GetCustomAttributes(false); var attribute = classAttributes.SingleOrDefault(a => a is RecordAttribute) as RecordAttribute; if (attribute == null) { throw new InvalidDefinitionException(); } this.Type = recordType; this.FixedLength = attribute.FixedLength; this.PageSize = attribute.PageSize; this.DuplicatedPointerCount = attribute.DuplicatedPointerCount; this.Allocation = attribute.Allocation; this.VariableOption = attribute.VariableOption; this.UsesIndexBalancing = attribute.UsesIndexBalancing; this.IsCompressed = attribute.IsCompressed; this.FreeSpaceThreshold = attribute.FreeSpaceThreshold; this.SystemDataOption = attribute.SystemDataOption; this.PrimaryKeyNumber = attribute.PrimaryKeyNumber; this.DefaultByte = attribute.DefaultByte; this.DllPath = attribute.DllPath; this.DependencyPaths = attribute.DependencyPaths; this.PathType = attribute.PathType; this.UriHost = attribute.UriHost; this.UriUser = attribute.UriUser; this.UriDbName = attribute.UriDbName; this.UriTable = attribute.UriTable; this.UriDbFile = attribute.UriDbFile; this.UriFile = attribute.UriFile; this.UriPassword = attribute.UriPassword; this.UriPrompt = attribute.UriPrompt; this.AbsolutePath = attribute.AbsolutePath; this.RelativeDirectory = attribute.RelativeDirectory; this.RelativePath = attribute.RelativePath; this.OwnerName = attribute.OwnerName; this.OwnerNameOption = attribute.OwnerNameOption; this.OpenMode = attribute.OpenMode; if (this.VariableOption == RecordVariableOption.NotVariable) { this.VariableFieldCapacity = 0; } else { this.VariableFieldCapacity = attribute.VariableFieldCapacity; } this.RejectCount = attribute.RejectCount; var properties = recordType .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.CanRead || p.CanWrite); var fields = new List <FieldInfo>(); foreach (var property in properties) { var propertyAttributes = property.GetCustomAttributes(false); var fieldAttribute = propertyAttributes .SingleOrDefault(a => a is FieldAttribute) as FieldAttribute; if (fieldAttribute == null) { continue; } if (fieldAttribute.Position + fieldAttribute.Length > attribute.FixedLength) { throw new InvalidDefinitionException(); } var field = new FieldInfo(fieldAttribute, this, propertyAttributes.Where(a => a is KeySegmentAttribute).Select(a => (KeySegmentAttribute)a), property); field.Name = property.Name; field.FullName = recordType.FullName + "." + property.Name; fields.Add(field); Resource._fieldMemberInfoDictionary[property] = field; if (property.CanRead) { Resource._fieldMemberInfoDictionary[property.GetGetMethod()] = field; } if (property.CanWrite) { Resource._fieldMemberInfoDictionary[property.GetSetMethod()] = field; } Resource._fieldNameDictionary[field.FullName] = field; } foreach (var field in fields) { CheckKeyTypeLength(field); } this.Fields = fields.ToArray(); var keyNumbers = fields.SelectMany(f => f.KeySegments.Select(s => s.KeyNumber)).Distinct().OrderBy(n => n).ToArray(); var keys = new List <KeyInfo>(); var keyAttributes = classAttributes .Where(a => a is KeyAttribute) .Select(a => (KeyAttribute)a); foreach (var keyNumber in keyNumbers) { var keyAttribute = keyAttributes .SingleOrDefault(a => a.KeyNumber == keyNumber); if (keyAttribute == null) { keyAttribute = new KeyAttribute(keyNumber); } var keySegments = fields .Where(f => f.KeySegments.Any(s => s.KeyNumber == keyNumber)) .Select(f => f.KeySegments.Single(s => s.KeyNumber == keyNumber)) .OrderBy(s => s.Index); if (keySegments.Count() == 0 || keySegments .Select((s, i) => s.Index != i) .Any(r => r)) { throw new InvalidDefinitionException(); } keySegments.Last().IsSegmentKey = false; var key = new KeyInfo(keyAttribute, keySegments, this); keys.Add(key); var matches = new bool[key.Length]; foreach (var keySegment in keySegments) { for (var i = 0; i < keySegment.Field.Length; i++) { if (matches[keySegment.Position + i]) { throw new InvalidDefinitionException(); } matches[keySegment.Position + i] = true; } } } this.Keys = new KeyCollection(keys); foreach (var field in this.Fields) { var keyTypeAttribute = Resource.GetKeyTypeAttribute(field.KeyType); if (keyTypeAttribute != null) { if (!keyTypeAttribute.ValidateLength(field.Length)) { throw new InvalidDefinitionException(); } } if (field.NullType == NullType.Nullable) { var nullFlagField = this.Fields.SingleOrDefault(f => f.NullType == NullType.NullFlag && f.Position == field.Position - 1); if (nullFlagField == null || !field.KeySegments.All(s => nullFlagField.KeySegments.Any(ns => ns.Key == s.Key && ns.Index == s.Index - 1))) { throw new InvalidDefinitionException(); } field.NullFlagField = nullFlagField; } } var isModArray = new bool[this.FixedLength]; foreach (var keySegment in keys.Where(k => !k.IsModifiable).SelectMany(k => k.Segments)) { for (var i = 0; i < keySegment.Field.Length; i++) { isModArray[keySegment.Field.Position + i] = true; } } foreach (var field in this.Fields) { for (var i = 0; i < field.Length; i++) { if (isModArray[field.Position + i]) { field.IsModifiable = false; break; } } } }
public static KeyValue MaximumComplement(KeyInfo key, params object[] segmentValues) { return(new KeyValue(key, segmentValues, false)); }