Exemple #1
0
 /// <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}'.");
        }
    }