EF कोड पहले "अमान्य स्तंभ नाम 'डिस्क्रिमिनेटर'" लेकिन कोई विरासत नहीं है


154

मेरे पास अपने डेटाबेस में एक तालिका है, जिसे SEntries कहा जाता है (क्रिएट टेबल स्टेटमेंट के नीचे देखें)। इसमें एक प्राथमिक कुंजी, विदेशी कुंजियों का एक जोड़ा और इसके बारे में कुछ खास नहीं है। मेरे डेटाबेस में उसी के समान कई टेबल हैं, लेकिन किसी कारण से, यह टेबल EF प्रॉक्सी क्लास पर "डिस्क्रिमिनेटर" कॉलम के साथ समाप्त हो गई।

इस तरह से कक्षा को 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; }
            ...
    }

जब मैं उस तालिका में एक नई पंक्ति जोड़ने का प्रयास करता हूं, तो मुझे त्रुटि मिलती है:

System.Data.SqlClient.SqlException: Invalid column name 'Discriminator'.

यह समस्या केवल तब होती है जब आप अपनी C # क्लास को दूसरी क्लास से इनहेरिट कर रहे होते हैं, लेकिन सेनेट्री को कुछ भी विरासत में नहीं मिलता है (जैसा कि आप ऊपर देख सकते हैं)।

इसके अलावा, एक बार जब मुझे डीबगर पर टूल-टिप मिलती है, जब मैं सेनेट्री प्रॉपर्टी के लिए EMData उदाहरण पर माउस करता हूं, तो यह प्रदर्शित होता है:

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...

कोई सुझाव या विचार जहां इस मुद्दे की तह तक जाना है? मैंने मेज, प्राथमिक कुंजी और कुछ अन्य चीजों के नाम बदलने की कोशिश की, लेकिन कुछ भी काम नहीं करता है।

एसक्यूएल-तालिका:

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

16
अगले व्यक्ति के लिए, जो यह जानने की कोशिश में कुछ समय बिताएगा कि क्या हुआ है, कोड पर एक अन्य स्थान पर, मेरे पास एक वर्ग था जो सेनेट्री से विरासत में मिला था, भले ही यह एक ऐसा वर्ग नहीं है जो कभी भी डीबी पर संग्रहीत किया जाएगा। । तो मुझे जो कुछ करने की ज़रूरत थी, वह [NotMapped] उस वर्ग की विशेषता के रूप में जोड़ना था!
मार्सेलो कैल्बुकी

मुझे यह त्रुटि हो रही है अगर मैं Identitymodel.cs में ApplicationUser वर्ग पर [NotMapped] नहीं डाल रहा हूँ
हेमांशु भल्ला

जवाबों:


319

यह बताता है कि एंटिटी फ्रेमवर्क यह मान लेगा कि किसी भी वर्ग को जो पोको वर्ग से विरासत में मिला है, जिसे डेटाबेस में एक टेबल पर मैप किया गया है, उसे एक डिस्क्रिमिनेटर कॉलम की आवश्यकता होती है, भले ही व्युत्पन्न वर्ग को डीबी में नहीं बचाया जाएगा।

समाधान काफी सरल है और आपको बस [NotMapped]व्युत्पन्न वर्ग की विशेषता के रूप में जोड़ना होगा ।

उदाहरण:

class Person
{
    public string Name { get; set; }
}

[NotMapped]
class PersonViewModel : Person
{
    public bool UpdateProfile { get; set; }
}

अब, भले ही आप डेटाबेस पर व्यक्ति वर्ग को व्यक्ति तालिका में मैप करते हैं, लेकिन व्युत्पन्न वर्ग के कारण "डिस्क्रिमिनेटर" कॉलम नहीं बनाया जाएगा [NotMapped]

एक अतिरिक्त टिप के रूप में, आप उन [NotMapped]गुणों का उपयोग कर सकते हैं जिन्हें आप DB पर एक फ़ील्ड में मैप नहीं करना चाहते हैं।


7
ठीक है तो मेरे जीवन के 3 घंटे हो जाते हैं; (लेकिन सभी समान रूप से tyvm। मुझे केवल स्पष्ट होने के लिए भी जोड़ना चाहिए ... व्युत्पन्न वर्ग किसी भी तरह से कोने में किसी भी तरह से इस्तेमाल नहीं किया जा सकता है: दृढ़ता और ईएफ अभी भी कोशिश करते हैं और उन में ... बहुत भ्रामक आकर्षित करेगा।
rism

12
अगर आपको [NotMapped] नहीं मिलता है, तो कृपया "असेंबली फ्रेमवर्क" से प्रोजेक्ट के लिए: "System.ComponentModel.DataAnnotations" में एक संदर्भ जोड़ें।
XandrUu

9
System.ComponentModel.DataAnnotations.Schema का उपयोग कर;
यार्गादोन

6
लेकिन मेरे मामले में मुझे चाइल्ड क्लास का उपयोग करके db टेबल में कॉलम जोड़ने के लिए एक वर्ग विरासत में मिला है। इसलिए मैं इसे काम करने के लिए इस नोट किए गए विशेषता का उपयोग नहीं कर सकता। इस मामले में मेरा क्या समाधान होना चाहिए?
सोहैब ने

4
मेरे मामले में मैप न किए जाने से मदद नहीं मिली। मैंने सभी दृश्य-पत्रों में नहीं देखा है
हेमांशु भल्ला

44

यहाँ धाराप्रवाह एपीआई सिंटेक्स है।

http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-fluent-api-samples.aspx

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName { 
        get {
            return this.FirstName + " " + this.LastName;
        }
    }
}

class PersonViewModel : Person
{
    public bool UpdateProfile { get; set; }
}


protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // ignore a type that is not mapped to a database table
    modelBuilder.Ignore<PersonViewModel>();

    // ignore a property that is not mapped to a database column
    modelBuilder.Entity<Person>()
        .Ignore(p => p.FullName);

}

क्या केवल [NotMapped]विशेषता जोड़ना बेहतर नहीं होगा ?
कीथ

1
@ मेरे जवाब में धाराप्रवाह एपीआई का उपयोग करते हुए एक कॉलम को अनदेखा करने का तरीका है, जो [NotMapped] जैसे विशेषताओं का उपयोग नहीं करता है
वाल्टर स्टबोसज़

1
कीथ यह पसंदीदा उत्तर है जो मुझे लगता है क्योंकि अब एक कोड-प्रथम मानक की ओर बढ़ रहे हैं और वाल्टर का उत्तर इस परिदृश्य के लिए बेहतर अनुकूल है, खासकर यदि आप डीबी माइग्रेशन का उपयोग करके समाप्त होते हैं।
ताहिर खालिद

जहाँ आपको विपरीत समस्या (यानी एक POCO वर्ग से विरासत में मिलने वाली EF बाउंड क्लास) यह एकमात्र तरीका था जिससे मैं EF के साथ डेटा मॉडल को प्रदूषित किए बिना काम कर सकता था।
पॉल माइकल्स

8

मुझे बस इसका सामना करना पड़ा और मेरी समस्या System.ComponentModel.DataAnnotations.Schema.TableAttributeएक ही तालिका के संदर्भ में दोनों संस्थाओं के होने से हुई ।

उदाहरण के लिए:

[Table("foo")]
public class foo
{
    // some stuff here
}

[Table("foo")]
public class fooExtended
{
    // more stuff here
}

मेरे लिए यह तय fooकरने से दूसरे को बदलना foo_extendedऔर मैं अब टेबल प्रति प्रकार (टीपीटी) का उपयोग कर रहा हूं


यह मेरे लिए काम नहीं किया:The entity types 'AtencionMedica' and 'AtencionMedicaAP' cannot share table 'AtencionMedicas' because they are not in the same type hierarchy
जेम्स Reategui

धन्यवाद, मेरी मदद की, धाराप्रवाह एपीआई का उपयोग करते हुए एक ही मुद्दा था: var entity = modelBuilder.Entity<EntityObject>().ToTable("ENTITY_TABLE")और फिर एक ही EntityObjectया उसी का उपयोग करके एक और लाइन ENTITY_TABLE
मथिज फ्लिस्ट्रा

4

एक अन्य परिदृश्य जहां ऐसा होता है, जब आपके पास एक आधार वर्ग और एक या अधिक उपवर्ग होते हैं, जहां कम से कम एक उपवर्ग अतिरिक्त गुण प्रस्तुत करता है:

class Folder {
  [key]
  public string Id { get; set; }

  public string Name { get; set; }
}

// Adds no props, but comes from a different view in the db to Folder:
class SomeKindOfFolder: Folder {
}

// Adds some props, but comes from a different view in the db to Folder:
class AnotherKindOfFolder: Folder {
  public string FolderAttributes { get; set; }
}

यदि इन्हें DbContextनीचे की तरह मैप किया जाता है, तो "अमान्य स्तंभ नाम 'डिस्क्रिमिनेटर'" त्रुटि तब होती है जब Folderआधार प्रकार पर आधारित किसी भी प्रकार तक पहुँचा जाता है:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.Entity<Folder>().ToTable("All_Folders");
  modelBuilder.Entity<SomeKindOfFolder>().ToTable("Some_Kind_Of_Folders");
  modelBuilder.Entity<AnotherKindOfFolder>().ToTable("Another_Kind_Of_Folders");
}

मैंने पाया कि समस्या को ठीक करने के लिए, हम Folderएक बेस क्लास (जो कि इसमें मैप नहीं किया गया है OnModelCreating()) के प्रॉप्स को निकालते हैं, जैसे - OnModelCreatingअपरिवर्तित होना चाहिए:

class FolderBase {
  [key]
  public string Id { get; set; }

  public string Name { get; set; }
}

class Folder: FolderBase {
}

class SomeKindOfFolder: FolderBase {
}

class AnotherKindOfFolder: FolderBase {
  public string FolderAttributes { get; set; }
}

यह समस्या को समाप्त करता है, लेकिन मुझे नहीं पता कि क्यों!


धन्यवाद, मीटैक्स - जिसकी कीमत मुझे एक या दो घंटे थी, लेकिन सबसे खराब हिस्सा यह था, मुझे पहले भी यह समस्या रही होगी, क्योंकि मेरे पास आधार कक्षाएं थीं। डम्बर मुझे एक साल बाद कहते हैं, "अरे, ऐसा लग रहा है कि यह बेस क्लास कुछ नहीं कर रहा है। मुझे लगता है कि मैं इसे हटा दूंगा ..." और मेरे जीवन का एक घंटा चला गया कि मैं कभी वापस नहीं आऊंगा। यह क्यों आवश्यक है? काश मैं ईएफ को बेहतर तरीके से समझ पाता।
वेल्स

2

मुझे एक और स्थिति में त्रुटि मिलती है, और यहाँ समस्या और समाधान हैं:

मेरे पास एक ही बेस क्लास से 2 कक्षाएं हैं जिनका नाम LevledItem है:

public partial class Team : LeveledItem
{
   //Everything is ok here!
}
public partial class Story : LeveledItem
{
   //Everything is ok here!
}

लेकिन उनके DbContext में, मैंने कुछ कोड कॉपी किए लेकिन उनमें से एक का नाम बदलना भूल गया:

public class MFCTeamDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Other codes here
        modelBuilder.Entity<LeveledItem>()
            .Map<Team>(m => m.Requires("Type").HasValue(ItemType.Team));
    }

public class ProductBacklogDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Other codes here
        modelBuilder.Entity<LeveledItem>()
            .Map<Team>(m => m.Requires("Type").HasValue(ItemType.Story));
    }

हां, दूसरा मैप <टीम> मैप <स्टोरी> होना चाहिए। और यह पता लगाने के लिए मुझे आधे दिन का समय देना पड़ा!


2

मुझे एक समान समस्या थी, बिल्कुल वैसी ही स्थिति नहीं और फिर मैंने इस पोस्ट को देखा । आशा है कि यह किसी की मदद करता है। जाहिरा तौर पर मैं अपने EF इकाई मॉडल में से एक का उपयोग एक प्रकार के लिए एक आधार वर्ग के रूप में कर रहा था जो कि मेरे dbcontext में db सेट के रूप में निर्दिष्ट नहीं था। इस समस्या को ठीक करने के लिए मुझे एक आधार वर्ग बनाना था जिसमें सभी प्रकार के दो गुण सामान्य थे और दो प्रकारों के बीच नए आधार वर्ग से विरासत में मिला था।

उदाहरण:

//Bad Flow
    //class defined in dbcontext as a dbset
    public class Customer{ 
       public int Id {get; set;}
       public string Name {get; set;}
    }

    //class not defined in dbcontext as a dbset
    public class DuplicateCustomer:Customer{ 
       public object DuplicateId {get; set;}
    }


    //Good/Correct flow*
    //Common base class
    public class CustomerBase{ 
       public int Id {get; set;}
       public string Name {get; set;}
    }

    //entity model referenced in dbcontext as a dbset
    public class Customer: CustomerBase{

    }

    //entity model not referenced in dbcontext as a dbset
    public class DuplicateCustomer:CustomerBase{

       public object DuplicateId {get; set;}

    }

1

यह त्रुटि मेरे साथ हुई क्योंकि मैंने निम्नलिखित कार्य किया था

  1. मैंने डेटाबेस में तालिका का कॉलम नाम बदल दिया है
  2. (मैंने Update Model from databaseEdmx में उपयोग नहीं किया ) मैंने डेटाबेस स्कीमा में परिवर्तन का मिलान करने के लिए मैन्युअल रूप से संपत्ति का नाम बदला
  3. मैंने कक्षा में संपत्ति के नाम को बदलने के लिए कुछ रिफैक्टिंग किया, जो डेटाबेस स्कीमा और एड्मक्स में मॉडल के समान है

हालांकि यह सब, मुझे यह त्रुटि मिली

इसलिए what to do

  1. मैंने Edmx से मॉडल हटा दिया
  2. राइट क्लिक और Update Model from database

यह मॉडल को पुनर्जीवित करेगा, और इकाई ढांचा will नहीं give you this error

आशा है कि यह आपकी मदद करेगा


1

पुराना क्यू, लेकिन पश्चात के लिए ... यह भी होता है (.NET कोर 2.1) यदि आपके पास स्व-संदर्भित नेविगेशन संपत्ति ("माता-पिता" या "बच्चे" एक ही प्रकार के हैं), लेकिन आईडी संपत्ति का नाम क्या है ईएफ की उम्मीद है। यही है, मेरे पास अपनी कक्षा में एक "आईडी" संपत्ति थी WorkflowBase, जिसे बुलाया गया था , और इसमें संबंधित बाल चरणों की एक सरणी थी, जो कि प्रकार के भी थे WorkflowBase, और यह उन्हें एक गैर-मौजूद "वर्कफ़्लोबेस" (नाम मैं) के साथ जोड़ने की कोशिश करता रहा। मान लीजिए कि यह एक प्राकृतिक / पारंपरिक डिफ़ॉल्ट के रूप में पसंद किया जाता है)। मैं स्पष्ट रूप से उपयोग कर इसे कॉन्फ़िगर करने के लिए किया था HasMany(), WithOne()और HasConstraintName()कैसे पार करने के लिए यह बताने के लिए। लेकिन मैंने कुछ घंटे बिताते हुए सोचा कि समस्या स्थानीय रूप से ऑब्जेक्ट की प्राथमिक कुंजी को मैप करने में है, जिसे मैंने अलग-अलग तरीकों से एक गुच्छा ठीक करने का प्रयास किया था, लेकिन जो हमेशा काम कर रहा था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.