OData / OData/WebApi

Key convention conflicts with use of KeyAttribute

Open
#809 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

P3
Dominant language
C#
Stars
864
Forks
467
PR merge metrics
No merged PRs in 30d

Description

Assemblies affected

Unknown. Wherever Key conventions are implemented.

Reproduce steps

Create an entity class that has an Int32 ID column but no KeyAttribute, and has any column (e.g. Status1) of type String that is KeyAttribute. Link this class to any other entity that uses the FK column. See two classes below.

    public partial class Status {
        public Status() {
            this.Jobs = new HashSet<Jobs2>();
        }
        // no attributes detected
        public virtual ICollection<Jobs2> Jobs { get; set; }
        [Required, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Int32 ID { get; set; }
        [Key, Required, MaxLength(32), StringLength(32)]
        public String Status1 { get; set; }
        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public String Name { get; set; }
    }
    public partial class Jobs2 {
        public Jobs2() {
        }
        [ForeignKey("Status")]
        public virtual Status Status1 { get; set; }
        [Key, Required, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Int32 ID { get; set; }
        [Required, MaxLength(32), StringLength(32)]
        public String Status { get; set; }
    }

This code sequence blows up with the given message in Actual Result section.

    var builder = new ODataConventionModelBuilder();
    builder.DataServiceVersion = new Version(2, 0);
    builder.MaxDataServiceVersion = new Version(4, 0);
    foreach (var es in new Type[] { typeof(Jobs2), typeof(Status) }) {
        var esconfig = builder.AddEntity(es);
        builder.AddEntitySet(es.Name, esconfig);
    }
    var edm = builder.GetEdmModel();

Remove the Status.ID property completely, and the example works correctly. Rename that property to any other name (not picked up by a convention), and the example works correctly. The other attributes do not affect the error.

Expected result

This should not generate any errors. It incorrectly includes the ID column when a key has already been established via KeyAttribute.

Actual result

Misleading error message, because of the erroneously included column.

The dependent property types 'System.String' are not same as the principal key types 'System.Int32,System.String'. The dependent and principal must each contain the same number of elements and must have the same types.

Additional details

Key convention must be smarter and examine the entity's use of KeyAttribute before "helping".

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 with ODataConventionModelBuilder and the GetEdmModel() path, reproducing the issue with the Status and Jobs2 classes shown in the report. Check how key conventions interact with KeyAttribute when building the entity model. Done means the model builds without errors and does not include Status.ID in the principal key when Status1 is explicitly marked as the key.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.