Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

invalid FK field name #35034

Closed
mastras23 opened this issue Nov 3, 2024 · 4 comments
Closed

invalid FK field name #35034

mastras23 opened this issue Nov 3, 2024 · 4 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@mastras23
Copy link

for entities

 [Index("Name", IsUnique = true)]
    public class Revision
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int RevisionId { get; set; }
        public virtual ICollection<ScrapRegister> ScrapRegisters { get; set; } = [];
        public virtual ICollection<Component> Components { get; set; } = [];
        public virtual ICollection<AssemblyComponent> AssemblyComponents { get; set; } = [];
   ...}

    public class ScrapRegister
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [ForeignKey("Revision")]
        public int RevisionId { get; set; } = 1;
        public virtual Revision Revision { get; set; }
  ...}

    [PrimaryKey(nameof(ComponentId), nameof(RevisionId))]
    public class Component
    {
        [StringLength(32)]
        [MaxLength(32)]
        [Unicode(false)]
        public string ComponentId { get; set; } 

        [ForeignKey("Revision")]
        public int RevisionId { get; set; } = 1;
        public virtual Revision Revision { get; set; }
     ...}

this query

                var qry = _context
                    .Revisions
                    .Select(r => new RevisionDTO
                    {
                        RevisionId = r.RevisionId,
                        ScrapsInRevision = r.ScrapRegisters.**Count**(),
                        AssemblyComponentsInRevision = r.AssemblyComponents.Count(),
                        ComponentsInRevision = r.Components.Count(),
                        ...
                    });
                
                List<RevisionDTO> r = await qry
                    .OrderBy(r => r.RevisionId)
                    .ToListAsync(ct)
                    .ConfigureAwait(false);

generates reference to no existent field RevisionId1

SELECT [r].[RevisionId], (
    SELECT COUNT(*)
    FROM [Scrap].[ScrapRegisters] AS [s]
    WHERE [r].[RevisionId] = [s].[**RevisionId1**]) AS [ScrapsInRevision], (
    SELECT COUNT(*)
    FROM [Scrap].[AssemblyComponents] AS [a]
    WHERE [r].[RevisionId] = [a].[RevisionId]) AS [AssemblyComponentsInRevision], (
    SELECT COUNT(*)
    FROM [Scrap].[Components] AS [c]
    WHERE [r].[RevisionId] = [c].[RevisionId]) AS [ComponentsInRevision], [r].[Closed], [r].[Created], [r].[CreatorId], [r].[Description], [r].[Disabled], [r].[Name], 0 AS [RowStatus]
FROM [Scrap].[Revisions] AS [r]
	<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
	<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.10" />
	<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.10">
	<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.10" />
@maumar
Copy link
Contributor

maumar commented Nov 4, 2024

I'm unable to reproduce this. Here is the full listing I used:

using var ctx = new MyContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();


var qry = ctx
    .Revisions
    .Select(r => new RevisionDTO
    {
        RevisionId = r.RevisionId,
        ScrapsInRevision = r.ScrapRegisters.Count(),
        AssemblyComponentsInRevision = r.AssemblyComponents.Count(),
        ComponentsInRevision = r.Components.Count(),
    });

List<RevisionDTO> r = await qry
    .OrderBy(r => r.RevisionId)
    .ToListAsync()
    .ConfigureAwait(false);

public class MyContext : DbContext
{
    public DbSet<Revision> Revisions { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
                .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Repro;Trusted_Connection=True;MultipleActiveResultSets=true")
                .LogTo(Console.WriteLine, LogLevel.Information)
                .EnableSensitiveDataLogging();
    }
}


public class RevisionDTO
{
    public int RevisionId { get; set; }

    public int ScrapsInRevision { get; set; }
    public int AssemblyComponentsInRevision { get; set; }
    public int ComponentsInRevision { get; set; }
}

[Index("Name", IsUnique = true)]
public class Revision
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int RevisionId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<ScrapRegister> ScrapRegisters { get; set; } = [];
    public virtual ICollection<Component> Components { get; set; } = [];
    public virtual ICollection<AssemblyComponent> AssemblyComponents { get; set; } = [];
}

public class ScrapRegister
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [ForeignKey("Revision")]
    public int RevisionId { get; set; } = 1;
    public virtual Revision Revision { get; set; }
}

[PrimaryKey(nameof(ComponentId), nameof(RevisionId))]
public class Component
{
    [StringLength(32)]
    [MaxLength(32)]
    [Unicode(false)]
    public string ComponentId { get; set; }

    [ForeignKey("Revision")]
    public int RevisionId { get; set; } = 1;
    public virtual Revision Revision { get; set; }
}

public class AssemblyComponent
{
    public int Id { get; set; }
}

This generates the following sql:

SELECT [r].[RevisionId], (
    SELECT COUNT(*)
    FROM [ScrapRegister] AS [s]
    WHERE [r].[RevisionId] = [s].[RevisionId]) AS [ScrapsInRevision], (
    SELECT COUNT(*)
    FROM [AssemblyComponent] AS [a]
    WHERE [r].[RevisionId] = [a].[RevisionId]) AS [AssemblyComponentsInRevision], (
    SELECT COUNT(*)
    FROM [Component] AS [c]
    WHERE [r].[RevisionId] = [c].[RevisionId]) AS [ComponentsInRevision]
FROM [Revisions] AS [r]
ORDER BY [r].[RevisionId]

@mastras23 please modify the code above so that it reproduces the issue.

@mastras23
Copy link
Author

mastras23 commented Nov 4, 2024 via email

@roji
Copy link
Member

roji commented Nov 12, 2024

@mastras23 please clean up your comment and code just above - we need to be able to read what you're posting. Refer to this guide for writing markdown on github.

@mastras23
Copy link
Author

I don't know what factors cause it to show up in my project but not in your code, I used a workaround, maybe someone else will have a more clear situation,

@mastras23 mastras23 closed this as not planned Won't fix, can't repro, duplicate, stale Nov 13, 2024
@ajcvickers ajcvickers added the closed-no-further-action The issue is closed and no further action is planned. label Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

4 participants