Skip to content

Dapper.Contrib Feature Request w/ code: Customizable Key Conventions #54

Description

@Reris

This is linked to DapperLib/Dapper#1093 Set a custom Key Attribute

Currently, a Model class has to use [Key] or [ExplicitKey] to define an Id.
If there's none and a property named "id", it will get used as a [Key], meaning it assumes an autoincremental/generated column value.

For my purpose of a CQRS read model, where the id already has a well defined value, this means that every read model would need an [ExplicitKey] above the Id property.

Instead, to keep the model clean and separated, I suggest to add a customizable convention delegate which would be used inside of KeyPropertiesCache & ExplicitKeyPropertiesCache:

        public enum KeyKind
        {
            None,
            UseValues,
            Generated
        }

        public delegate KeyKind KeyDefinitionConvention([NotNull] PropertyInfo current, [NotNull] [ItemNotNull] PropertyInfo[] all);

This allows easy implementations of custom comventions, like in my case, using Id as explicit key by default, or by using DataAnnotations [Key] etc, while it's still separated from any other TypeMapping-concerns.

The current behavior would be represented as:

        SqlMapperExtensions.ConventionalKeyDefinition = SqlMapperExtensions.DefaultConventionalKeyDefinition;
        private static KeyKind DefaultConventionalKeyDefinition(PropertyInfo property, PropertyInfo[] all)
        {
            if (string.Equals(property.Name, "id", StringComparison.OrdinalIgnoreCase)
                && !all.Any(
                    p => p.GetCustomAttribute<ExplicitKey>() != null
                         || p.GetCustomAttribute<Key>() != null))
            {
                return KeyKind.Generated;
            }

            if (property.GetCustomAttribute<ExplicitKey>() != null)
            {
                return KeyKind.UseValues;
            }

            if (property.GetCustomAttribute<Key>() != null)
            {
                return KeyKind.Generated;
            }

            return KeyKind.None;
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions