Mam tabelę w mojej bazie danych o nazwie SEntries (patrz poniżej instrukcja CREATE TABLE). Ma klucz podstawowy, kilka kluczy obcych i nic w tym specjalnego. Mam wiele tabel w mojej bazie danych podobnych do tej, ale z jakiegoś powodu ta tabela zakończyła się kolumną „Discriminator” w klasie EF Proxy.
Oto jak klasa jest zadeklarowana w C #:
public class SEntry
{
public long SEntryId { get; set; }
public long OriginatorId { get; set; }
public DateTime DatePosted { get; set; }
public string Message { get; set; }
public byte DataEntrySource { get; set; }
public string SourceLink { get; set; }
public int SourceAppId { get; set; }
public int? LocationId { get; set; }
public long? ActivityId { get; set; }
public short OriginatorObjectTypeId { get; set; }
}
public class EMData : DbContext
{
public DbSet<SEntry> SEntries { get; set; }
...
}
Kiedy próbuję dodać nowy wiersz do tej tabeli, pojawia się błąd:
System.Data.SqlClient.SqlException: Invalid column name 'Discriminator'.
Ten problem występuje tylko wtedy, gdy dziedziczysz klasę C # z innej klasy, ale SEntry nie dziedziczy z niczego (jak widać powyżej).
Oprócz tego, gdy otrzymam podpowiedź dotyczącą debugera, po umieszczeniu wskaźnika myszy na instancji EMData dla właściwości SEntries, wyświetla się ona:
base {System.Data.Entity.Infrastructure.DbQuery<EM.SEntry>} = {SELECT
[Extent1].[Discriminator] AS [Discriminator],
[Extent1].[SEntryId] AS [SEntryId],
[Extent1].[OriginatorId] AS [OriginatorId],
[Extent1].[DatePosted] AS [DatePosted],
[Extent1].[Message] AS [Message],
[Extent1].[DataEntrySource] AS [DataE...
Jakieś sugestie lub pomysły, gdzie dojść do sedna tego problemu? Próbowałem zmienić nazwę tabeli, klucza podstawowego i kilku innych rzeczy, ale nic nie działa.
Tabela SQL:
CREATE TABLE [dbo].[SEntries](
[SEntryId] [bigint] IDENTITY(1125899906842624,1) NOT NULL,
[OriginatorId] [bigint] NOT NULL,
[DatePosted] [datetime] NOT NULL,
[Message] [nvarchar](500) NOT NULL,
[DataEntrySource] [tinyint] NOT NULL,
[SourceLink] [nvarchar](100) NULL,
[SourceAppId] [int] NOT NULL,
[LocationId] [int] NULL,
[ActivityId] [bigint] NULL,
[OriginatorObjectTypeId] [smallint] NOT NULL,
CONSTRAINT [PK_SEntries] PRIMARY KEY CLUSTERED
(
[SEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[SEntries] WITH CHECK ADD CONSTRAINT [FK_SEntries_ObjectTypes] FOREIGN KEY([OriginatorObjectTypeId])
REFERENCES [dbo].[ObjectTypes] ([ObjectTypeId])
GO
ALTER TABLE [dbo].[SEntries] CHECK CONSTRAINT [FK_SEntries_ObjectTypes]
GO
ALTER TABLE [dbo].[SEntries] WITH CHECK ADD CONSTRAINT [FK_SEntries_SourceApps] FOREIGN KEY([SourceAppId])
REFERENCES [dbo].[SourceApps] ([SourceAppId])
GO
ALTER TABLE [dbo].[SEntries] CHECK CONSTRAINT [FK_SEntries_SourceApps]
GO
źródło
Odpowiedzi:
Okazuje się, że Entity Framework zakłada, że każda klasa, która dziedziczy po klasie POCO, która jest mapowana do tabeli w bazie danych, wymaga kolumny Discriminator, nawet jeśli klasa pochodna nie zostanie zapisana w bazie danych.
Rozwiązanie jest dość proste i wystarczy dodać
[NotMapped]
jako atrybut klasy pochodnej.Przykład:
Teraz, nawet jeśli zamapujesz klasę Person na tabelę Person w bazie danych, kolumna „Discriminator” nie zostanie utworzona, ponieważ klasa pochodna ma
[NotMapped]
.Jako dodatkową wskazówkę możesz użyć
[NotMapped]
właściwości, których nie chcesz mapować na pole w bazie danych.źródło
Oto składnia Fluent API.
http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-fluent-api-samples.aspx
źródło
[NotMapped]
atrybut?Właśnie to napotkałem, a mój problem był spowodowany posiadaniem dwóch jednostek, które
System.ComponentModel.DataAnnotations.Schema.TableAttribute
odnoszą się do tej samej tabeli.na przykład:
zmiana drugiej z
foo
nafoo_extended
naprawioną dla mnie i teraz używam tabeli według typu (TPT)źródło
The entity types 'AtencionMedica' and 'AtencionMedicaAP' cannot share table 'AtencionMedicas' because they are not in the same type hierarchy
var entity = modelBuilder.Entity<EntityObject>().ToTable("ENTITY_TABLE")
a następnie kolejną linię używającą tego samegoEntityObject
lub tego samegoENTITY_TABLE
.Innym scenariuszem, w którym tak się dzieje, jest sytuacja, gdy masz klasę bazową i jedną lub więcej podklas, w których co najmniej jedna z podklas wprowadza dodatkowe właściwości:
Jeśli są one odwzorowane w
DbContext
poniższy sposób, podczasFolder
uzyskiwania dostępu do dowolnego typu opartego na typie podstawowym pojawia się błąd „„ Nieprawidłowa nazwa kolumny ”Dyskryminator” :Okazało się, że aby rozwiązać problem, wyodrębniamy właściwości
Folder
do klasy bazowej (która nie jest mapowanaOnModelCreating()
) w ten sposób -OnModelCreating
powinno pozostać niezmienione:Eliminuje to problem, ale nie wiem dlaczego!
źródło
Błąd pojawia się w innej sytuacji, a oto problem i rozwiązanie:
Mam 2 klasy pochodzące z tej samej klasy bazowej o nazwie LevledItem:
Ale w ich DbContext skopiowałem trochę kodu, ale zapomniałem zmienić jedną z nazw klas:
Tak, druga mapa <Team> powinna być mapą <Story>. I pół dnia kosztowało mnie to rozgryzienie!
źródło
Miałem podobny problem, nie dokładnie te same warunki i wtedy zobaczyłem ten post . Mam nadzieję, że to komuś pomoże. Najwyraźniej użyłem jednego z moich modeli jednostek EF, klasy bazowej dla typu, który nie został określony jako zestaw db w moim kontekście dbcontext. Aby rozwiązać ten problem, musiałem utworzyć klasę bazową, która miałaby wszystkie właściwości wspólne dla obu typów i dziedziczyła z nowej klasy bazowej spośród dwóch typów.
Przykład:
źródło
ten błąd występuje ze mną, ponieważ wykonałem następujące czynności
Update Model from database
w Edmx) Zmieniłem nazwę ręcznie Nazwa właściwości, aby dopasować ją do zmiany w schemacie bazy danychChociaż to wszystko, mam ten błąd
więc
what to do
Update Model from database
spowoduje to ponowne wygenerowanie modelu, a struktura jednostki
will
niegive you this error
mam nadzieję, że to ci pomoże
źródło
Stara Q, ale dla potomnych ... zdarza się również (.NET Core 2.1), jeśli masz odwołującą się do siebie właściwość nawigacji („Parent” lub „Children” tego samego typu), ale nazwa właściwości Id nie jest tym, czym EF oczekuje. Oznacza to, że moja klasa miała właściwość „Id” o nazwie
WorkflowBase
, która miała tablicę powiązanych kroków podrzędnych, które również były typuWorkflowBase
, i próbowała powiązać je z nieistniejącym „WorkflowBaseId” (nazwa i załóżmy, że preferuje jako naturalne / konwencjonalne domyślne). Miałem jawnie skonfigurować go za pomocąHasMany()
,WithOne()
iHasConstraintName()
aby poinformować go jak przemierzać. Spędziłem jednak kilka godzin, myśląc, że problem polega na „lokalnym” mapowaniu klucza podstawowego obiektu, który próbowałem naprawić na kilka różnych sposobów, ale który prawdopodobnie zawsze działał.źródło