EF কোড প্রথম "অবৈধ কলামের নাম 'বৈষম্যমূলক'" তবে কোনও উত্তরাধিকার নেই


154

আমার ডাটাবেসে সেন্ট্রি নামে একটি টেবিল রয়েছে (তৈরি টেবিলের বিবৃতি নীচে দেখুন)। এটিতে একটি প্রাথমিক কী, কয়েকটি বিদেশী কী এবং এটিতে বিশেষ কিছু নেই। আমার ডাটাবেসে সেইরকম অনেকগুলি সারণী রয়েছে তবে কোনও কারণে, এই টেবিলটি 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'.

এই সমস্যাটি কেবল তখনই ঘটে যখন আপনি নিজের সি # ক্লাসটি অন্য শ্রেণি থেকে উত্তরাধিকারী হচ্ছেন, তবে সেন্ট্রি কোনও কিছু থেকে উত্তরাধিকার সূত্রে আসছেন না (যেমন আপনি উপরে দেখতে পারেন)।

এগুলি ছাড়াও, যখন আমি সেন্টরিজ সম্পত্তিটির জন্য ইএমডাটা উদাহরণটি মাউস করি তখন আমি ডিবাগারে সরঞ্জাম-টিপটি পাই, এটি প্রদর্শিত হয়:

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
পরবর্তী ব্যক্তির জন্য যারা এটি বের করার চেষ্টা করে কিছুটা সময় ব্যয় করবেন, যা ঘটেছিল তা হল কোডের অন্য কোনও জায়গায়, আমার কাছে একটি শ্রেণি ছিল যা সেন্ট্রি থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছিল, যদিও এটি কোনও শ্রেণি নয় যা কখনও ডিবিতে সঞ্চিত থাকে না । সুতরাং আমার যা করার দরকার তা হ'ল [নটম্যাপেড ]টিকে সেই শ্রেণীর একটি বৈশিষ্ট্য হিসাবে যুক্ত করা!
মার্সেলো ক্যালবুচি

আমি যদি আইডেন্টিটি
মডেল সি-

উত্তর:


319

সরে দাঁড়িয়েছে যে সত্তা ফ্রেমওয়ার্কটি ধরে নেবে যে কোনও ক্লাস যে পোকো ক্লাস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত যা ডাটাবেসে একটি টেবিলের সাথে ম্যাপ করা আছে তার জন্য একটি ডিসক্রিমিনেটর কলাম প্রয়োজন, এমনকি উত্পন্ন শ্রেণিটি ডিবিতে সংরক্ষণ করা হবে না।

সমাধানটি বেশ সহজ এবং আপনাকে কেবল [NotMapped]উত্পন্ন শ্রেণীর একটি বৈশিষ্ট্য হিসাবে যুক্ত করতে হবে ।

উদাহরণ:

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

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

এখন, আপনি ডাটাবেসে পার্সোন টেবিলটিতে পার্সোন ক্লাস ম্যাপ করলেও, "বৈষম্যমূলক" কলাম তৈরি করা হবে না কারণ উদ্ভূত শ্রেণীর রয়েছে [NotMapped]

অতিরিক্ত টিপ হিসাবে, আপনি [NotMapped]ডিবিতে কোনও ক্ষেত্রের মানচিত্র করতে চান না এমন বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন ।


7
ঠিক আছে তাই আমার জীবনের 3 ঘন্টা চলে যায়; (তবে tyvm সব একই। আমার স্পষ্টতই যোগ করা উচিত ... উদ্ভূত শ্রেণিগুলি কোনওভাবে ব্যবহার করা হয়নি বরং কোণে সমস্ত উপায় হতে পারে: অধ্যবসায় এবং EF তবুও চেষ্টা করবে এবং এগুলিকে এঁকে দেবে ... খুব বিভ্রান্তিকর
রিজম

12
যদি আপনি [নটম্যাপড] না খুঁজে পান তবে দয়া করে একটি প্রকল্পটি "এসেম্বলি ফ্রেমওয়ার্ক" থেকে "সিস্টেম.কম্পোনমেন্টমোডেল.ডাটাঅনোটেশন" যুক্ত করুন।
XandrUu

9
System.Comp घटकModel.DataAnnotations.Schema ব্যবহার করে;
ইগারাডন

6
তবে আমার ক্ষেত্রে চাইল্ড ক্লাস ব্যবহার করে ডিবি টেবিলে কলাম যুক্ত করতে আমি একটি বর্গ উত্তরাধিকার সূত্রে পেয়েছি। সুতরাং আমি এটি ব্যবহার করতে এই নটম্যাপযুক্ত বৈশিষ্ট্যটি ব্যবহার করতে পারি না। এক্ষেত্রে আমার সমাধান কী হওয়া উচিত?
সোহাইব

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
@ কীথ আমার উত্তরটি কীভাবে ফ্লুয়েট এপিআই ব্যবহার করে একটি কলাম উপেক্ষা করবেন, যা [নটম্যাপড] মতো বৈশিষ্ট্যগুলি ব্যবহার করে না
ওয়াল্টার স্টাবোসজ

1
কীথ এটি আমার পছন্দের উত্তর বলে মনে হয় কারণ এখন কোনও কোড-প্রথম মানের দিকে এগিয়ে চলেছে এবং ওয়াল্টরের উত্তর এই দৃশ্যের জন্য ভাল উপযুক্ত, বিশেষত যদি আপনি ডিবি স্থানান্তর ব্যবহার করে শেষ করেন।
তাহির খালিদ

যেখানে আপনার বিপরীত সমস্যা রয়েছে (যেমন এবং EF বাউন্ড শ্রেণি যা একটি পোকো ক্লাসের উত্তরাধিকার সূত্রে আসে) আমি কেবলমাত্র এটাই উপায়টি EF এর সাথে ডেটা মডেলকে দূষিত না করে কাজ করতে পারি।
পল মাইকেলস 14

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
জেমস রেটেগই

ধন্যবাদ, আমাকে সহায়তা করেছেন, ফ্লুয়েন্ট এপিআই ব্যবহার করে একই সমস্যাটি হয়েছে: 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 টি ক্লাস রয়েছে:

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

তবে তাদের ডিবি কনটেক্সটে আমি কিছু কোড অনুলিপি করেছিলাম তবে শ্রেণীর নামগুলির একটি পরিবর্তন করতে ভুলে যাই:

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 database এডএমএক্স করিনি) ডাটাবেস স্কিমার পরিবর্তনের সাথে মিলে আমি নিজেই সম্পত্তির নামটির নামকরণ করেছি
  3. আমি ক্লাসে থাকা সম্পত্তিটির নাম পরিবর্তন করে এডএমএক্সের ডাটাবেস স্কিমা এবং মডেলগুলির অনুরূপ হতে কিছু রিফ্যাক্টরিং করেছি

যদিও এই সব, আমি এই ত্রুটি পেয়েছি

সুতরাং what to do

  1. আমি মডেলটি এডএমএক্স থেকে মুছে ফেলেছি
  2. রাইট ক্লিক এবং Update Model from database

এটি মডেলটি পুনরায় উত্পন্ন করবে এবং সত্তা কাঠামো will নয় give you this error

আশা করি এটি আপনাকে সাহায্য করবে


1

ওল্ড কিউ, তবে উত্তরোত্তর জন্য ... এটিতেও ঘটে (। নেট কোর ২.১) যদি আপনার স্ব-রেফারেন্সিং নেভিগেশন সম্পত্তি থাকে ("প্যারেন্ট" বা একই ধরণের "শিশু") তবে আইডি সম্পত্তি নামটি কী তা নয় EF আশা করে। এটি হ'ল, আমার ক্লাসে আমার একটি "আইডি" সম্পত্তি WorkflowBaseছিল, এবং এটি সম্পর্কিত শিশু ধাপগুলির একটি অ্যারে ছিল, এটিও টাইপ ছিল WorkflowBaseএবং এটি তাদের অস্তিত্বহীন "ওয়ার্কফ্লোবেসআইডি" (নামটি আই এর সাথে যুক্ত করার চেষ্টা করে) রেখেছিল মনে করুন এটি প্রাকৃতিক / প্রচলিত ডিফল্ট হিসাবে পছন্দ করে)। আমি স্পষ্টভাবে ব্যবহার করে এটি কনফিগার করতে ছিল HasMany(), WithOne()এবং HasConstraintName()কিভাবে তর্ক তা বলতে। তবে আমি এই সমস্যাটি স্থানীয়ভাবে 'স্থানীয়ভাবে' অবজেক্টের প্রাথমিক কীটি ম্যাপিংয়ে ভেবে কয়েক ঘন্টা ব্যয় করেছি, যা আমি বিভিন্ন উপায়ে একটি গোছা ঠিক করার চেষ্টা করেছি তবে যা সম্ভবত সর্বদা কাজ করে যাচ্ছিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.