Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
233 views
in Technique[技术] by (71.8m points)

c# - Invalid column name in one of contexts - EF Core 2.2.6

In my application I have multiple database contexts. There is only one called MainDataContext where I do my migrations. I have a problem which one mapping where I have no idea why EF thinks there is one property which indeed do not exists.

Check the mapping above.

MainDataContext:

public class PriceListMap : IEntityTypeConfiguration<PriceListEntity>
    {
        public void Configure(EntityTypeBuilder<PriceListEntity> builder)
        {
            builder.ToTable("PriceLists");

            builder.HasKey(x => x.Id);

            builder.HasDiscriminator<PriceListType>(nameof(PriceListEntity.Type))
                .HasValue<ExchangePriceListEntity>(PriceListType.Exchange)
                .HasValue<DumpPriceListEntity>(PriceListType.Dump)
                .HasValue<ContainerRentalPriceListEntity>(PriceListType.ContainerRental);
        }
    }


public class ExchangePriceListMap : IEntityTypeConfiguration<ExchangePriceListEntity>
    {
        public void Configure(EntityTypeBuilder<ExchangePriceListEntity> builder)
        {
            builder.HasMany(x => x.Prices)
                .WithOne(x => x.PriceList)
                .HasForeignKey(x => x.PriceListId)
                .OnDelete(DeleteBehavior.Cascade);
        }
    }

    public class ExchangePriceListItemMap : IEntityTypeConfiguration<ExchangePriceListItemEntity>
    {
        public void Configure(EntityTypeBuilder<ExchangePriceListItemEntity> builder)
        {
            builder.ToTable("ExchangePriceListItems");

            builder.HasOne(x => x.Container)
                .WithMany()
                .OnDelete(DeleteBehavior.Restrict)
                .HasForeignKey(x => x.ContainerId);

            builder.HasOne(x => x.Article)
                .WithMany()
                .OnDelete(DeleteBehavior.Restrict)
                .HasForeignKey(x => x.ArticleId);

            builder.Property(x => x.Price).HasColumnType("decimal(18,2)");
        }
    }

SecondDataContext

public class PriceListMap : IEntityTypeConfiguration<PriceList>
    {
        public void Configure(EntityTypeBuilder<PriceList> builder)
        {
            builder.ToTable("PriceLists");

            builder.HasKey(x => x.Id);

            builder.HasDiscriminator<PriceListType>(nameof(PriceList.Type))
                .HasValue<ExchangePriceList>(PriceListType.Exchange)
                .HasValue<DumpPriceList>(PriceListType.Dump)
                .HasValue<ContainerRentalPriceList>(PriceListType.ContainerRental);
        }
    }

    public class ExchangePriceListMap : IEntityTypeConfiguration<ExchangePriceList>
    {
        public void Configure(EntityTypeBuilder<ExchangePriceList> builder)
        {
            var navigation = builder.Metadata.FindNavigation(nameof(ExchangePriceList.Prices));

            navigation.SetPropertyAccessMode(PropertyAccessMode.Field);

            builder.HasMany(x => x.Prices)
                .WithOne(x => x.PriceList)
                .HasForeignKey(x => x.PriceListId)
                .OnDelete(DeleteBehavior.Cascade);
        }
    }

    public class ExchangePriceListItemMap : IEntityTypeConfiguration<ExchangePriceListItem>
    {
        public void Configure(EntityTypeBuilder<ExchangePriceListItem> builder)
        {
            builder.OwnsOne(x => x.Price, a =>
            {
                a.Property(x => x.Amount)
                    .HasColumnName("Price")
                    .HasColumnType("decimal(18,2)");
                a.OwnsOne(x => x.Currency, c =>
                {
                    c.Property(p => p.Code).HasColumnName("Currency");
                });
            });

            builder.HasOne(x => x.Container)
                .WithMany()
                .OnDelete(DeleteBehavior.Restrict)
                .HasForeignKey(x => x.ContainerId);

            builder.HasOne(x => x.Article)
                .WithMany()
                .OnDelete(DeleteBehavior.Restrict)
                .HasForeignKey(x => x.ArticleId);

        }
    }

What I do as a test is:

 var context = serviceScope.ServiceProvider.GetRequiredService<MainDataContext>();
 var a = context.ExchangePriceListItems.ToList();

This generates below SQL:

info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT [e].[Id], [e].[ArticleId], [e].[ContainerId], [e].[Currency], [e].[Price], [e].[PriceListId] FROM [ExchangePriceListItems] AS [e]

This indeed is working. However doing the same operation on SecondContext gives an exception while generating such SQL:

fail: Microsoft.EntityFrameworkCore.Database.Command[20102] Failed executing DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='300'] SELECT [e].[Id], [e].[ArticleId], [e].[ContainerId], [e].[ContractedExchangeId], [e].[PriceListId], [e].[Id], [e].[Price], [e].[Id], [e].[Currency] FROM [ExchangePriceListItems] AS [e]

The question is where EF using this context takes this [e].[ContractedExchangeId] column. This does not exists and somehow in background EF think it exists. [EDIT] Huh it also try select ID three times

There is database schema in SQL table:

[Id] [bigint] IDENTITY(1,1) NOT NULL,

[Currency] [int] NOT NULL,

[Price] [decimal](18, 2) NOT NULL,

[ArticleId] [bigint] NOT NULL,

[ContainerId] [bigint] NOT NULL,

[PriceListId] [bigint] NOT NULL,

Thanks in advance!

question from:https://stackoverflow.com/questions/65649258/invalid-column-name-in-one-of-contexts-ef-core-2-2-6

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...