DapperLib / DapperLib/Dapper.Contrib

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

Open
#54 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
293
Forks
109
PR merge metrics
No merged PRs in 30d

Description

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;
        }

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating KeyPropertiesCache and ExplicitKeyPropertiesCache, then read the existing [Key], [ExplicitKey], and conventional "id" handling. Compare the proposed KeyKind convention with current mapping behavior and determine how configuration should preserve the default rules. Done means custom conventions can distinguish generated keys from value-supplied keys without requiring attributes.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
database
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.