2

First I will expose the code that reproduces the problem. Then I will explain the problem.

I have two entities, Employee and ContactForm (address, email, telephone...):

public class Employee
{
    public long Id { get; set; }
    public string UserName { get; set; }


    public ObservableCollection<ContactForm> Telephones { get; set; } = new ObservableCollection<ContactForm>();
    public ObservableCollection<ContactForm> Emails { get; set; } = new ObservableCollection<ContactForm>();
}



public class ContactForm
{
    public long Id { get; set; }
    public string Contact { get; set; }
}

This is the fluent API configuration of Employee:

public class EmployeeConfiguration : IEntityTypeConfiguration<Employee>
{
    public void Configure(EntityTypeBuilder<Employee> paramEmployeefiguracion)
    {
        paramEmployeefiguracion.ToTable("Employees");


        paramEmployeefiguracion.HasKey(o => o.Id);
        paramEmployeefiguracion.Property<long>(o => o.Id)
            .HasColumnName("IDEmployee")
            .HasColumnType("bigint")
            .IsRequired();

        paramEmployeefiguracion.Property<string>(o => o.UserName)
            .HasColumnName("UserName")
            .HasColumnType("varchar(500)")
            .IsRequired();



        paramEmployeefiguracion
            .HasMany(x => x.Telephones)
            .WithOne()
            .HasForeignKey("IDEmployee");


        paramEmployeefiguracion
            .HasMany(x => x.Emails)
            .WithOne()
            .HasForeignKey("IDEmployee");
    }
}

This is the fluent API configuration of ContactForms:

public class ContactsFormsConfiguration : IEntityTypeConfiguration<ContactForm>
{
    public void Configure(EntityTypeBuilder<ContactForm> paramContactFormConfiguration)
    {
        paramContactFormConfiguration.ToTable("ContactsForms");


        paramContactFormConfiguration.HasKey(o => o.Id);
        paramContactFormConfiguration.Property<long>(o => o.Id)
            .HasColumnName("IDContactForm")
            .HasColumnType("bigint")
            .IsRequired();

        //SHADOW PROPERTY
        paramContactFormConfiguration.Property<long>("IDContactFormType")
            .HasColumnName("IDContactFormType")
            .HasColumnType("bigint")
            .IsRequired();

        paramContactFormConfiguration.Property<string>(o => o.Contact)
            .HasColumnName("ContactForm")
            .HasColumnType("varchar(200)");
    }
}

And this is the query:

public async Task<Employee?> GetEmployeeWithTelephonesAndEmails(long paramIdEmployee)
{
    return await _context.Employees
            .AsNoTracking()
            .Include(x => x.Telephones.Where(y => EF.Property<long>(y, "IDContactFormType") == 2))
            //.Include(x => x.Emails.Where(y => EF.Property<long>(y, "IDContactFormType") == 3))
            .FirstOrDefaultAsync(x => x.Id == paramIdEmployee);
}

This are the two tables in my database:

  • Employee(IDEmployee, UserName)
  • ContactsForms(IDContactForm, ContactForm, IDEmployee, IDContactFormType)
  • ContactsFormsTypes(IDContactFormType, Type)

Now, the problem.

The problem is that if in the Employee entity I use the two collections (telephones and emails), I get the error that the column name EmployeeId is not valid.

If for example, in Employee I comment the collection Emails, I comment the configuration in the configuration of the employee and I comment the include in the query, it works. I include the telephones.

But when I uncomment the Emails collection and want to include both, telephones and emails, I get the error.

This is the query that EF sends to the database:

SELECT [t].[IDEmployee], [t].[UserName], [t0].[IDContactForm], [t0].[ContactForm], [t0].[EmployeeId], [t0].[IDContactFormType], [t0].[IDEmployee], [t1].[IDContactForm], [t1].[ContactForm], [t1].[EmployeeId], [t1].[IDContactFormType], [t1].[IDEmployee]
FROM (
    SELECT TOP(1) [e].[IDEmployee], [e].[UserName]
    FROM [Employees] AS [e]
    WHERE [e].[IDEmployee] = @__paramIdEmployee_0
) AS [t]
LEFT JOIN (
    SELECT [c].[IDContactForm], [c].[ContactForm], [c].[EmployeeId], [c].[IDContactFormType], [c].[IDEmployee]
    FROM [ContactsForms] AS [c]
    WHERE [c].[IDContactFormType] = CAST(2 AS bigint)
) AS [t0] ON [t].[IDEmployee] = [t0].[EmployeeId]
LEFT JOIN (
    SELECT [c0].[IDContactForm], [c0].[ContactForm], [c0].[EmployeeId], [c0].[IDContactFormType], [c0].[IDEmployee]
    FROM [ContactsForms] AS [c0]
    WHERE [c0].[IDContactFormType] = CAST(3 AS bigint)
) AS [t1] ON [t].[IDEmployee] = [t1].[IDEmployee]
ORDER BY [t].[IDEmployee], [t0].[IDContactForm]',N'@__paramIdEmployee_0 bigint',@__paramIdEmployee_0=1

As you can see, in the left join, it tries to use [c].[EmployeeId], where c0 is the table ContactsForms.

The query that is send when I comment the Emails collection, when the query works, is this:

SELECT [t].[IDEmployee], [t].[UserName], [t0].[IDContactForm], [t0].[ContactForm], [t0].[IDContactFormType], [t0].[IDEmployee]
FROM (
    SELECT TOP(1) [e].[IDEmployee], [e].[UserName]
    FROM [Employees] AS [e]
    WHERE [e].[IDEmployee] = @__paramIdEmployee_0
) AS [t]
LEFT JOIN (
    SELECT [c].[IDContactForm], [c].[ContactForm], [c].[IDContactFormType], [c].[IDEmployee]
    FROM [ContactsForms] AS [c]
    WHERE [c].[IDContactFormType] = CAST(2 AS bigint)
) AS [t0] ON [t].[IDEmployee] = [t0].[IDEmployee]
ORDER BY [t].[IDEmployee]',N'@__paramIdEmployee_0 bigint',@__paramIdEmployee_0=1

In this case, it uses [c].[IDEmployee] in the left join, so it is correct.

Thanks.

Álvaro García
  • 18,114
  • 30
  • 102
  • 193
  • Sounds like you want a composite key `(long IDContactFormType, int IDEmployee)` – Aluan Haddad Jul 13 '23 at 17:27
  • IDContactFormType is not part of the key of ContactForms. It is just to know the kind of contact form (address, telephone, email). But the key is a surogate key, IDContactForm, a big int autonumeric. – Álvaro García Jul 14 '23 at 08:08
  • Maybe I misunderstand what you're trying to do but what I was talking about was differentiating between the two observable collections. Furthermore, the enum value can it be part of a composite key. – Aluan Haddad Jul 19 '23 at 14:46

0 Answers0