/// <summary> /// 构造函数 /// </summary> /// <param name="entityType">实体类型。实体必须是标记了<see cref="DatabaseEntityAttribute"/>性质的类型</param> /// <exception cref="ArgumentNullException">实体类型为空时产生</exception> /// <exception cref="ArgumentException">实体类型未标记为<see cref="DatabaseEntityAttribute"/>性质时产生</exception> public DatabaseEntityHelper(Type entityType) { if (entityType == null) { throw new ArgumentNullException("entityType"); } object[] attributes = null; attributes = entityType.GetCustomAttributes(typeof(DatabaseEntityAttribute), false); if (attributes == null || attributes.Length < 1) { throw new ArgumentException("entityType does not have DatabaseEntityAttribute", "entityType"); } this.databaseEntityAttribute = (DatabaseEntityAttribute)attributes[0]; this.entityType = entityType; }
public void Validate(ICustomAutoGeneratedServiceInfo customAutoGeneratedServiceInfo) { _repositoryInterfaceType = customAutoGeneratedServiceInfo.ImplementedInterface; if (!_repositoryInterfaceType.IsInterface) { throw new Exception($"The repository class should be an interface. The class is '{_repositoryInterfaceType.FullName}'."); } if (_repositoryInterfaceType.GetInterfaces().Length > 0) { throw new Exception($"The repository interface'{_repositoryInterfaceType.FullName}' cannot have base interfaces."); } var attribute = _repositoryInterfaceType.GetCustomAttributes().FirstOrDefault(x => x.GetType() == typeof(DataRepositoryAttribute)); if (attribute is not DataRepositoryAttribute dataRepositoryAttribute) { throw new Exception($"Attribute '{typeof(DataRepositoryAttribute)}' is missing in data repository '{_repositoryInterfaceType}'."); } if (_repositoryInterfaceType.GetProperties().ToList().Count > 0) { throw new Exception($"No properties are supported in repository interfaces that use attribute '{typeof(DataRepositoryAttribute)}'."); } _databaseEntityType = dataRepositoryAttribute.DatabaseEntityType; foreach (var methodInfo in _repositoryInterfaceType.GetMethods()) { var attributes = methodInfo.GetCustomAttributes().ToList(); if (attributes.Count == 0) { var validAttributeTypes = new Type[] { typeof(RepositoryMethodMetadataForAddAttribute), typeof(RepositoryMethodMetadataForAddOrUpdateAttribute), typeof(RepositoryMethodMetadataForDeleteAttribute), typeof(RepositoryMethodMetadataForSelectAttribute) }; throw new Exception($"Only methods with one of the following attributes are supported in repository interface '{_repositoryInterfaceType}': {string.Join(",", validAttributeTypes.Select(x => x.FullName))}."); } foreach (var currentAttribute in attributes) { if (currentAttribute is RepositoryMethodMetadataForAddAttribute repositoryMethodMetadataForAddAttribute) { ValidateRepositoryMethodSignature(methodInfo, new[] { _databaseEntityType }, new TypeInfo(_databaseEntityType)); _repositoryMethodMetadataForAdd.Add(new RepositoryMethodMetadata <RepositoryMethodMetadataForAddAttribute>(repositoryMethodMetadataForAddAttribute, methodInfo)); } else if (currentAttribute is RepositoryMethodMetadataForAddOrUpdateAttribute repositoryMethodMetadataForAddOrUpdateAttribute) { ValidateRepositoryMethodSignature(methodInfo, new[] { _databaseEntityType }, new TypeInfo(_databaseEntityType)); _repositoryMethodMetadataForAddOrUpdate.Add(new RepositoryMethodMetadata <RepositoryMethodMetadataForAddOrUpdateAttribute>(repositoryMethodMetadataForAddOrUpdateAttribute, methodInfo)); } else if (currentAttribute is RepositoryMethodMetadataForDeleteAttribute repositoryMethodMetadataForDeleteAttribute) { ValidateRepositoryMethodSignature(methodInfo, new[] { _databaseEntityType }, new TypeInfo("System", "Void")); _repositoryMethodMetadataForDelete.Add(new RepositoryMethodMetadata <RepositoryMethodMetadataForDeleteAttribute>(repositoryMethodMetadataForDeleteAttribute, methodInfo)); } else if (currentAttribute is RepositoryMethodMetadataForSelectAttribute repositoryMethodMetadataForSelectAttribute) { if (repositoryMethodMetadataForSelectAttribute.IsSelectAll) { ValidateRepositoryMethodSignature(methodInfo, Type.EmptyTypes, new TypeInfo("System.Collections.Generic", "IReadOnlyList`1", new List <Type> { _databaseEntityType })); _repositoryMethodMetadataForSelectAll.Add(new RepositoryMethodMetadata <RepositoryMethodMetadataForSelectAttribute>(repositoryMethodMetadataForSelectAttribute, methodInfo)); } else { ValidateRepositoryMethodSignature(methodInfo, new Type[] { typeof(long) }, new TypeInfo(_databaseEntityType)); _repositoryMethodMetadataForSelectSingle.Add(new RepositoryMethodMetadata <RepositoryMethodMetadataForSelectAttribute>(repositoryMethodMetadataForSelectAttribute, methodInfo)); } } else { throw new Exception($"Invalid attribute specified for repository interface '{_repositoryInterfaceType}'."); } } } attribute = _databaseEntityType.GetCustomAttributes().FirstOrDefault(x => x.GetType() == typeof(DatabaseEntityAttribute)); _databaseEntityAttribute = attribute as DatabaseEntityAttribute; if (_databaseEntityAttribute == null) { throw new Exception($"Attribute '{typeof(DatabaseEntityAttribute)}' is missing in data repository entity class '{dataRepositoryAttribute.DatabaseEntityType}' in repository '{_repositoryInterfaceType}'."); } foreach (var propertyInfo in _databaseEntityType.GetProperties()) { var attributes = propertyInfo.GetCustomAttributes(); foreach (var currentAttribute in attributes) { if (currentAttribute is not ColumnAttribute columnAttribute) { continue; } var columnMetadata = new ColumnMetadata(columnAttribute, propertyInfo); if (columnAttribute.IsKeyAttribute) { if (_keyColumnMetadata == null) { _keyColumnMetadata = columnMetadata; } else { LogHelper.Context.Log.ErrorFormat("Only one key column attribute can be specified. Column {0} will not be used as a key column. Entity type with multiple key columns: '{1}'.", columnMetadata.ColumnName, _databaseEntityType); } } _columnsMetadata.Add(columnMetadata); } } if (_keyColumnMetadata == null) { throw new Exception($"No key column was specified in database entity type '{_databaseEntityType}'."); } }