বিদেশী মূল সীমাবদ্ধতার পরিচয় চক্র বা একাধিক ক্যাসকেড পাথের কারণ হতে পারে - কেন?


295

আমি কিছুক্ষণ ধরে এই নিয়ে কুস্তি করে যাচ্ছিলাম এবং কী ঘটছে তা পুরোপুরি বুঝতে পারছি না। আমার একটি কার্ড সত্তা রয়েছে যার মধ্যে সাইড রয়েছে (সাধারণত ২) - এবং কার্ড এবং সাইড উভয়েরই একটি স্টেজ থাকে। আমি ইএফ কোডফার্স্ট মাইগ্রেশন ব্যবহার করছি এবং মাইগ্রেশনগুলি এই ত্রুটির সাথে ব্যর্থ হচ্ছে:

বিদেশী মূল সীমাবদ্ধতার পরিচয় করিয়ে দেওয়া হচ্ছে 'এফকে_ডবো.সাইডস_ড্বো.কার্ডস_কার্ড আইডি' টেবিলের 'সাইডস'-এ চক্র বা একাধিক ক্যাসকেড পাথের কারণ হতে পারে। কোন পদক্ষেপ মুছে ফেলুন বা কোনও অ্যাকশন আপডেট করুন বা অন্যান্য বিদেশী কী বাধাগুলি সংশোধন করুন।

এখানে আমার কার্ড সত্তা:

public class Card
{
    public Card()
    {
        Sides = new Collection<Side>();
        Stage = Stage.ONE;
    }

    [Key]
    [Required]
    public virtual int CardId { get; set; }

    [Required]
    public virtual Stage Stage { get; set; }

    [Required]
    [ForeignKey("CardId")]
    public virtual ICollection<Side> Sides { get; set; }
}

এখানে আমার সাইড সত্তা:

public class Side
{
    public Side()
    {
        Stage = Stage.ONE;
    }

    [Key]
    [Required]     
    public virtual int SideId { get; set; } 

    [Required]
    public virtual Stage Stage { get; set; }

    [Required]
    public int CardId { get; set; }

    [ForeignKey("CardId")]
    public virtual Card Card { get; set; }

}

এবং এখানে আমার স্টেজ সত্তা:

public class Stage
{
    // Zero
    public static readonly Stage ONE = new Stage(new TimeSpan(0, 0, 0), "ONE");
    // Ten seconds
    public static readonly Stage TWO = new Stage(new TimeSpan(0, 0, 10), "TWO");

    public static IEnumerable<Stage> Values
    {
        get
        {
            yield return ONE;
            yield return TWO;
        }

    }

    public int StageId { get; set; }
    private readonly TimeSpan span;
    public string Title { get; set; }

    Stage(TimeSpan span, string title)
    {
        this.span = span;
        this.Title = title;
    }

    public TimeSpan Span { get { return span; } }
}

সবচেয়ে মজার বিষয় হ'ল আমি যদি আমার স্টেজ ক্লাসে নিম্নলিখিতটি যুক্ত করি:

    public int? SideId { get; set; }
    [ForeignKey("SideId")]
    public virtual Side Side { get; set; }

মাইগ্রেশন সফলভাবে চলে runs আমি যদি এসএসএমএস খুলি এবং টেবিলগুলিতে নজর রাখি তবে আমি দেখতে পাচ্ছি যে Stage_StageIdএতে যোগ হয়েছে Cards(প্রত্যাশিত / পছন্দসই), তবে Sidesএর কোনও উল্লেখ নেই Stage(প্রত্যাশিত নয়)।

আমি যদি তারপর যোগ

    [Required]
    [ForeignKey("StageId")]
    public virtual Stage Stage { get; set; }
    public int StageId { get; set; }

আমার সাইড ক্লাসে, আমি দেখতে পাচ্ছি StageIdকলামটি আমার Sideটেবিলে যুক্ত হয়েছে ।

এটি কাজ করছে, কিন্তু এখন আমার পুরো অ্যাপ্লিকেশন জুড়ে, এর কোনও রেফারেন্সে Stageএকটি রয়েছে SideIdযা কিছু ক্ষেত্রে সম্পূর্ণ অপ্রাসঙ্গিক। আমি সম্ভব হলে রেফারেন্স প্রোপার্টি সহ স্টেজ ক্লাসকে দূষিত না করে উপরের স্টেজ ক্লাসের উপর ভিত্তি করে আমার Cardএবং Sideসত্তাকে একটি Stageসম্পত্তি দিতে চাই ... আমি কী ভুল করছি?


7
রেফারেন্সগুলিতে নাল মানগুলিকে অনুমতি দিয়ে ক্যাসকেডিং মোছা অক্ষম করুন ... সুতরাং Sideক্লাসে নলযোগ্য পূর্ণসংখ্যা যোগ করুন এবং [Required]বৈশিষ্ট্যটি সরান =>public int? CardId { get; set; }
জায়েদার

2
মতিন কোর, আপনি সঙ্গে মুছতে ক্যাসকেড অক্ষম করা উচিত DeleteBehavior.Restrictবা DeleteBehavior.SetNull
সিনা লোটফি

উত্তর:


371

কারণ Stageহয় প্রয়োজনীয় , সব এক সাথে অধিকের সম্পর্ক যেখানে Stageজড়িত ডিলিট ডিফল্টভাবে সক্রিয় ক্যাসকেডিং থাকবে। এর অর্থ হ'ল, যদি আপনি কোনও Stageসত্তা মুছুন

  • মুছুন সরাসরি ক্যাসকেড হবে Side
  • ডিলিট সরাসরি নির্ঝর হবে Cardএবং কারণ Cardএবং Sideআছে ডিলিট ক্যাসকেডিং ডিফল্ট আবার তারপর থেকে নির্ঝর হবে সক্ষমিত-র সাথে একের সাথে অধিকের সম্পর্ক প্রয়োজনীয় CardকরতেSide

সুতরাং, আপনি দুই ক্যাসকেডিং ডিলিট পাথ আছে Stageকরতে Sideযা ব্যতিক্রম ঘটায় -।

আপনাকে হয় Stageকমপক্ষে একটি সত্তায় alচ্ছিক করতে হবে (যেমন [Required]বৈশিষ্ট্যগুলি থেকে বৈশিষ্ট্যটি সরিয়ে ফেলুন Stage) বা ফ্লুয়েন্ট এপিআই (ডেটা টিকা দিয়ে সম্ভব নয়) দিয়ে ক্যাসকেডিং মোছা অক্ষম করতে হবে:

modelBuilder.Entity<Card>()
    .HasRequired(c => c.Stage)
    .WithMany()
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Side>()
    .HasRequired(s => s.Stage)
    .WithMany()
    .WillCascadeOnDelete(false);

2
ধন্যবাদ স্লুমা। আপনি উপরে যেমন প্রদর্শিত হিসাবে আমি যদি সাবলীল এপিআই ব্যবহার করি তবে অন্যান্য ক্ষেত্রগুলি কি তাদের ক্যাসকেড আচরণ মুছে ফেলবে? উদাহরণস্বরূপ, কার্ডগুলি মোছার সময় আমার এখনও পাশের মোছার প্রয়োজন।
এসবি 2055

1
@ এসবি ২০৫৫: হ্যাঁ, এটি কেবলমাত্র সম্পর্কের উপর প্রভাব ফেলবে Stage। অন্যান্য সম্পর্ক অপরিবর্তিত রয়েছে।
স্লুমা

2
Wich বৈশিষ্ট্যগুলি ত্রুটি ঘটায় এমনটি জানার কোনও উপায় আছে কি? আমার একই সমস্যা হচ্ছে, এবং আমার ক্লাসগুলির দিকে তাকিয়ে আমি দেখতে পাচ্ছি না চক্রটি কোথায় রয়েছে
রদ্রিগো জুয়ারেজ

4
এটি কি তাদের বাস্তবায়নের সীমাবদ্ধতা? StageSideCard
Aaaaaa

1
ধরুন আমরা ক্যাসকেডঅনিলিটকে মিথ্যাতে সেট করেছি। তারপরে আমরা একটি মঞ্চের রেকর্ড সরিয়ে ফেললাম যা কার্ডের একটি রেকর্ডের সাথে সম্পর্কিত। কার্ড.সেজটে (এফকে) কী হবে? এটা কি একই থাকে? বা এটি নাল সেট করা আছে?
নিনবিত

61

আমার একটি টেবিল ছিল যা অন্যের সাথে একটি বৃত্তাকার সম্পর্ক ছিল এবং আমি একই ত্রুটি পাচ্ছিলাম। দেখা যাচ্ছে যে এটি বৈদেশিক কী সম্পর্কিত যা কার্যকর ছিল না। কীটি যদি অযোগ্য হয় না তবে সম্পর্কিত অবজেক্ট অবশ্যই মুছতে হবে এবং বিজ্ঞপ্তি সংক্রান্ত সম্পর্কগুলি এটির অনুমতি দেয় না। সুতরাং nlalable বিদেশী কী ব্যবহার করুন।

[ForeignKey("StageId")]
public virtual Stage Stage { get; set; }
public int? StageId { get; set; }

5
আমি [প্রয়োজনীয়] ট্যাগ সরানো কিন্তু পরাগধানী গুরুত্বপূর্ণ বিষয় ব্যবহার করতে ছিল int?পরিবর্তে intএটি nullable হতে দিন।
ভিএসবি

1
আমি ক্যাসকেড মোছা বন্ধ করার বিভিন্ন উপায় চেষ্টা করেছিলাম এবং কিছুই কার্যকর হয়নি - এটি এটিকে ঠিক করে দিয়েছে!
ambog36

5
আপনি যদি স্টেজটি বাতিল করতে না চান তবে এটি করা উচিত নয় (স্টেজটি মূল প্রশ্নের একটি প্রয়োজনীয় ক্ষেত্র ছিল)।
সিএফওয়াল

35

EF কোর এ কীভাবে করবেন তা নিয়ে যে কেউ ভাবছেন:

      protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
                {
                    relationship.DeleteBehavior = DeleteBehavior.Restrict;
                }
           ..... rest of the code.....

3
এটি সমস্ত সম্পর্কের উপর ক্যাসকেড মোছা বন্ধ করে দেবে। কিছু ব্যবহারের ক্ষেত্রে ক্যাসকেড মোছা পছন্দসই বৈশিষ্ট্য হতে পারে।
জ্বলুন

15
বিকল্পভাবে,builder.HasOne(x => x.Stage).WithMany().HasForeignKey(x => x.StageId).OnDelete(DeleteBehavior.Restrict);
বিস্কুট

@Biscuits হয় এক্সটেনশন পদ্ধতি সময়ের সাথে পরিবর্তিত বা তুমি ভুলে গেছ builder _ .Entity<TEntity>() _আগে HasOne() বলা যেতে পারে ...
ViRuSTriNiTy

1
@ ভাইরুস্ট্রিনিটি, আমার স্নিপেটটি 2 বছর বয়সী। তবে, আমি মনে করি আপনি ঠিক বলেছেন - আজকাল এটি যখন আপনি বাস্তবায়ন করতে চান IEntityTypeConfiguration<T>। আমি builder.Entity<T>সেই দিনগুলি দেখে পদ্ধতিটি মনে করি না , তবে আমি ভুল হতে পারি। তবুও, তারা দুজনেই কাজ করবে :)
বিস্কুট

21

আমি যখন একটি EF7 মডেল থেকে EF6 সংস্করণে স্থানান্তরিত হচ্ছিলাম তখন প্রচুর সত্ত্বার জন্য আমি এই ত্রুটিটি পেয়ে যাচ্ছিলাম। আমি একবারে প্রতিটি সত্তার মধ্য দিয়ে যেতে চাইনি, তাই আমি ব্যবহার করেছি:

builder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
builder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

2
এটি ক্লাসে যুক্ত করা উচিত (এস) যা ডিবি কনটেক্সট থেকে উত্তরাধিকার সূত্রে অনমোডেলক্রিয়াটিং পদ্ধতিতে। বিল্ডারটি ধরণের DbModelBuilder
কোডিংইউর লাইফ

এটি আমার পক্ষে কাজ করেছিল; .NET 4.7, EF 6. একটি হোঁচট খাতে আমি ত্রুটি পেয়েছি, সুতরাং যখন আমি এই সম্মেলনগুলি সরিয়ে দিয়ে মাইগ্রেশন লিপি দ্বারা পুনরায় জন্মানো হয়েছিল, তখন এটি সাহায্য করার জন্য উপস্থিত হয় নি। "-ফর্স" দিয়ে "অ্যাড-মাইগ্রেশন" চালানো সমস্ত কিছু সাফ করেছে এবং উপরের এই সম্মেলনগুলি সহ এটি পুনর্নির্মাণ করেছে। সমস্যার সমাধান ...
জেমস জয়েস

সেগুলি। নেট কোর, সেখানে কোন সমতুল্য নেই?
jjxtra

পরীক্ষা @jjxtra stackoverflow.com/questions/46526230/...
শন

20

আপনি ক্যাসকেডলিলেটটি মিথ্যা বা সত্য (আপনার মাইগ্রেশন আপ () পদ্ধতিতে) এ সেট করতে পারেন। আপনার প্রয়োজন উপর নির্ভর করে।

AddForeignKey("dbo.Stories", "StatusId", "dbo.Status", "StatusID", cascadeDelete: false);

2
@ মুসাকখির আপনার উত্তর দেওয়ার জন্য আপনাকে ধন্যবাদ। আপনার পথটি খুব মার্জিত এবং আরও বেশি - এটি যে সমস্যার মুখোমুখি হয়েছিল তার কাছে এটি আরও সঠিক এবং লক্ষ্যবস্তু!
Nozim Turakulov

UPবাহ্যিক ক্রিয়াকলাপ দ্বারা পদ্ধতিটি সংশোধন করা হতে পারে তা ভুলে যাবেন না ।
ডেমেন্টিক

8

.NET কোর-এ আমি অনডিলিট বিকল্পটি রেফারেন্সিয়ালএকশন.নো অ্যাকশনে পরিবর্তন করেছি

         constraints: table =>
            {
                table.PrimaryKey("PK_Schedule", x => x.Id);
                table.ForeignKey(
                    name: "FK_Schedule_Teams_HomeId",
                    column: x => x.HomeId,
                    principalTable: "Teams",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.NoAction);
                table.ForeignKey(
                    name: "FK_Schedule_Teams_VisitorId",
                    column: x => x.VisitorId,
                    principalTable: "Teams",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.NoAction);
            });

7

আমারও এই সমস্যাটি ছিল, আমি অনুরূপ থ্রেড থেকে এই উত্তরটি সঙ্গে সঙ্গে সমাধান করেছি

আমার ক্ষেত্রে, আমি কী মোছার উপর নির্ভরশীল রেকর্ডটি মুছতে চাইনি। যদি আপনার পরিস্থিতিতে এটি হয় তবে মাইগ্রেশনে কেবলমাত্র বুলিয়ান মানটি মিথ্যাতে পরিবর্তন করুন:

AddForeignKey("dbo.Stories", "StatusId", "dbo.Status", "StatusID", cascadeDelete: false);

সম্ভাবনাগুলি হ'ল, যদি আপনি এমন সম্পর্ক তৈরি করেন যা এই সংকলক ত্রুটি ছুঁড়ে ফেলে তবে ক্যাসকেড মোছা বজায় রাখতে চান; আপনার সম্পর্কগুলির সাথে আপনার একটি সমস্যা আছে।


6

আমি এটা ঠিক করেছি। আপনি যখন মাইগ্রেশন যুক্ত করবেন, আপ () পদ্ধতিতে এখানে একটি লাইন থাকবে:

.ForeignKey("dbo.Members", t => t.MemberId, cascadeDelete:True)

যদি আপনি শেষ থেকে ক্যাসকেডলিলেটটি মুছুন তবে এটি কাজ করবে।


5

কেবলমাত্র ডকুমেন্টেশনের উদ্দেশ্যে, ভবিষ্যতে আগত কারও কাছে এই জিনিসটিকে এত সহজ সমাধান করা যেতে পারে এবং এই পদ্ধতির সাহায্যে আপনি এমন একটি পদ্ধতি করতে পারেন যা এক সময় অক্ষম হয়ে যায় এবং আপনি সাধারণত নিজের পদ্ধতিতে অ্যাক্সেস করতে পারেন

প্রসঙ্গ ডাটাবেস শ্রেণিতে এই পদ্ধতিটি যুক্ত করুন:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}

1

এটি অদ্ভুত শোনায় এবং আমি জানি না কেন, তবে আমার ক্ষেত্রে এটি ঘটছিল কারণ আমার কানেকশনস্ট্রিং "ব্যবহার করছিল।" "ডেটা উত্স" বৈশিষ্ট্যে। একবার আমি এটিকে "লোকালহোস্ট" এ পরিবর্তন করেছিলাম এটি কবজির মতো কাজ করে। অন্য কোনও পরিবর্তনের দরকার পড়েনি।


1

ইন .NET কোর আমি সব উপরের উত্তরের সঙ্গে অভিনয় - কিন্তু কোন সাফল্য পায়নি। আমি ডিবি স্ট্রাকচারে অনেক পরিবর্তন করেছি এবং প্রতিবার নতুন মাইগ্রেশন যুক্ত করার চেষ্টা করেছিলাম update-database, তবে একই ত্রুটি পেয়েছি।

তারপরে প্যাকেজ ম্যানেজার কনসোল আমাকে ব্যতিক্রম remove-migrationনা করা পর্যন্ত আমি একে একে শুরু করেছিলাম :

'20170827183131 _ ***' স্থানান্তরটি ইতিমধ্যে ডাটাবেসে প্রয়োগ করা হয়েছে

এর পরে, আমি নতুন মাইগ্রেশন ( add-migration) এবং update-database সফলভাবে যুক্ত করেছি

সুতরাং আমার পরামর্শটি হ'ল: আপনার বর্তমান ডিবি স্টেট না হওয়া অবধি আপনার সমস্ত অস্থায়ী মাইগ্রেশন সাফ করুন।


1

বিদ্যমান উত্তরগুলি দুর্দান্ত I আমি কেবল যুক্ত করতে চেয়েছিলাম যে আমি অন্য কোনও কারণে এই ত্রুটির মধ্যে পড়েছিলাম। আমি একটি বিদ্যমান ডিবিতে একটি প্রাথমিক ইএফ মাইগ্রেশন তৈরি করতে চেয়েছিলাম কিন্তু আমি -IgnoreChanges ফ্ল্যাগটি ব্যবহার করিনি এবং একটি খালি ডেটাবেসে আপডেট-ডাটাবেস কমান্ড প্রয়োগ করেছি (বিদ্যমান ব্যর্থতার উপরেও)।

পরিবর্তে আমাকে এই কমান্ডটি চালাতে হয়েছিল যখন বর্তমান ডিবি কাঠামোটি বর্তমান রয়েছে:

Add-Migration Initial -IgnoreChanges

ডিবি স্ট্রাকচারটিতে সম্ভবত একটি আসল সমস্যা রয়েছে তবে বিশ্বকে একবারে এক ধাপ বাঁচাতে ...


1

সহজ উপায়, সম্পাদনা আপনার মাইগ্রেশন ফাইল (cascadeDelete: true)মধ্যে (cascadeDelete: false)তারপর আপনার শেষ মাইগ্রেশন তারপর সব ঠিক সঙ্গে এটি এর সমস্যা আপনার প্যাকেজ ম্যানেজার Console.if আপডেট-ডাটাবেজ কমান্ড নির্ধারণ করুন। অন্যথায় আপনার পূর্ববর্তী স্থানান্তরের ইতিহাস পরীক্ষা করে দেখুন, সেই জিনিসগুলি অনুলিপি করুন, আপনার শেষ মাইগ্রেশন ফাইলটিতে আটকান, তারপরে এটি একই কাজ করুন। এটা পুরোপুরি আমার জন্য কাজ করে।


1
public partial class recommended_books : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.RecommendedBook",
            c => new
                {
                    RecommendedBookID = c.Int(nullable: false, identity: true),
                    CourseID = c.Int(nullable: false),
                    DepartmentID = c.Int(nullable: false),
                    Title = c.String(),
                    Author = c.String(),
                    PublicationDate = c.DateTime(nullable: false),
                })
            .PrimaryKey(t => t.RecommendedBookID)
            .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: false) // was true on migration
            .ForeignKey("dbo.Department", t => t.DepartmentID, cascadeDelete: false) // was true on migration
            .Index(t => t.CourseID)
            .Index(t => t.DepartmentID);

    }

    public override void Down()
    {
        DropForeignKey("dbo.RecommendedBook", "DepartmentID", "dbo.Department");
        DropForeignKey("dbo.RecommendedBook", "CourseID", "dbo.Course");
        DropIndex("dbo.RecommendedBook", new[] { "DepartmentID" });
        DropIndex("dbo.RecommendedBook", new[] { "CourseID" });
        DropTable("dbo.RecommendedBook");
    }
}

যখন আপনার মাইগ্রেশন ব্যর্থ হয় তখন আপনাকে কয়েকটি বিকল্প দেওয়া হয়: 'বিদেশী কী বাধা উপস্থাপন করা হচ্ছে' এফকে_ড্বো.পরিষেপিত বুক_ড্বো.ড্যাপার্ট_ডেপরিডআইডি 'প্রস্তাবিতবুক' তে চক্র বা একাধিক ক্যাসকেড পাথের কারণ হতে পারে। কোন পদক্ষেপ মুছে ফেলুন বা কোনও অ্যাকশন আপডেট করুন বা অন্যান্য বিদেশী কী বাধাগুলি সংশোধন করুন। সীমাবদ্ধতা বা সূচক তৈরি করতে পারেনি। আগের ত্রুটিগুলি দেখুন See '

মাইগ্রেশন ফাইলে 'ক্যাসকেডডিলিট' মিথ্যা করে এবং 'আপডেট-ডাটাবেস' চালানোর মাধ্যমে 'অন্যান্য বিদেশী কী বাধার পরিবর্তনগুলি' ব্যবহারের উদাহরণ এখানে রয়েছে।


এটি এখানে আমার সমস্যার সমাধান করুন
বেলারামিনো ভিসেনজো

0

পূর্বোক্ত সমাধানগুলির কোনওটিই আমার পক্ষে কাজ করেনি। আমার যা করা দরকার তা হ'ল বিদেশী চাবিতে একটি নল ইনট (ইন্ট?) ব্যবহার করা হয়েছিল যা প্রয়োজনীয় ছিল না (বা নাল কলাম কী নয়) এবং তারপরে আমার কিছু স্থানান্তর মুছে ফেলতে হবে।

মাইগ্রেশন মুছে ফেলা দিয়ে শুরু করুন, তারপরে নল ইন্টি ব্যবহার করে দেখুন।

সমস্যা ছিল একটি পরিবর্তন এবং মডেল ডিজাইন উভয়ই। কোন কোড পরিবর্তন প্রয়োজন ছিল।


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