সত্তা ফ্রেমওয়ার্ক কোড প্রথম - একই টেবিল থেকে দুটি বিদেশী কী


260

আমি প্রথমে ইএফ কোডটি প্রথমে ব্যবহার শুরু করেছি, তাই আমি এই বিষয়টির মোট শুরুতে।

আমি টিম এবং ম্যাচগুলির মধ্যে সম্পর্ক তৈরি করতে চেয়েছিলাম:

1 ম্যাচ = 2 টিম (হোম, অতিথি) এবং ফলাফল।

আমি ভেবেছিলাম যে এ জাতীয় মডেল তৈরি করা সহজ, তাই আমি কোডিং শুরু করেছি:

public class Team
{
    [Key]
    public int TeamId { get; set;} 
    public string Name { get; set; }

    public virtual ICollection<Match> Matches { get; set; }
}


public class Match
{
    [Key]
    public int MatchId { get; set; }

    [ForeignKey("HomeTeam"), Column(Order = 0)]
    public int HomeTeamId { get; set; }
    [ForeignKey("GuestTeam"), Column(Order = 1)]
    public int GuestTeamId { get; set; }

    public float HomePoints { get; set; }
    public float GuestPoints { get; set; }
    public DateTime Date { get; set; }

    public virtual Team HomeTeam { get; set; }
    public virtual Team GuestTeam { get; set; }
}

এবং আমি একটি ব্যতিক্রম পাই:

রেফারেন্সিয়াল সম্পর্কের ফলে একটি চক্রীয় রেফারেন্স তৈরি হবে যা অনুমোদিত নয়। [সীমাবদ্ধতার নাম = ম্যাচ_গুয়েস্টটিম]

একই টেবিলে 2 টি বিদেশী কী সহ আমি কীভাবে এই জাতীয় মডেল তৈরি করতে পারি?

উত্তর:


296

এটা চেষ্টা কর:

public class Team
{
    public int TeamId { get; set;} 
    public string Name { get; set; }

    public virtual ICollection<Match> HomeMatches { get; set; }
    public virtual ICollection<Match> AwayMatches { get; set; }
}

public class Match
{
    public int MatchId { get; set; }

    public int HomeTeamId { get; set; }
    public int GuestTeamId { get; set; }

    public float HomePoints { get; set; }
    public float GuestPoints { get; set; }
    public DateTime Date { get; set; }

    public virtual Team HomeTeam { get; set; }
    public virtual Team GuestTeam { get; set; }
}


public class Context : DbContext
{
    ...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Match>()
                    .HasRequired(m => m.HomeTeam)
                    .WithMany(t => t.HomeMatches)
                    .HasForeignKey(m => m.HomeTeamId)
                    .WillCascadeOnDelete(false);

        modelBuilder.Entity<Match>()
                    .HasRequired(m => m.GuestTeam)
                    .WithMany(t => t.AwayMatches)
                    .HasForeignKey(m => m.GuestTeamId)
                    .WillCascadeOnDelete(false);
    }
}

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


3
যদি দুটি দলকে কেবল একবার খেলতে দেওয়া হয় তবে কী হবে?
ca9163d9

4
@ নিকডাব্লু: এটি ম্যাপিংয়ের ক্ষেত্রে নয় আপনাকে নিজের অ্যাপ্লিকেশনটিতে পরিচালনা করতে হবে। ম্যাপিং দৃষ্টিকোণ থেকে, জোড়া দুটি বার খেলতে দেওয়া হয় (প্রতিটি অতিথি এবং একবার বাড়িতে)।
লাডিস্লাভ Mrnka

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

1
@ মির্সিকাড্যান্স: এটি একই রকম। একটি পদ্ধতির অনর্গল এপিআই এবং অন্য ডেটা টিকা ব্যবহার করে।
লাডিস্লাভ মৃঙ্কা

1
যদি আমি উইল ক্যাসকেডঅনডিলিট মিথ্যা ব্যবহার করি তবে যদি আমি দলটিকে মুছতে চাই তবে এটি ত্রুটি ছুঁড়ে দিচ্ছে। 'টিম_হোমম্যাচস' অ্যাসোসিয়েশনসেটের একটি সম্পর্ক 'মুছে ফেলা' অবস্থায় রয়েছে। বহুবৃত্তির সীমাবদ্ধতাগুলি দেওয়া, একটি সম্পর্কিত 'টিমহোমম্যাচস_সরেজ' অবশ্যই 'মুছে ফেলা' অবস্থায় থাকতে হবে।
রূপেশ কুমার তিওয়ারি

55

ForeignKey()নেভিগেশন সম্পত্তিতে বৈশিষ্ট্য নির্দিষ্ট করাও সম্ভব :

[ForeignKey("HomeTeamID")]
public virtual Team HomeTeam { get; set; }
[ForeignKey("GuestTeamID")]
public virtual Team GuestTeam { get; set; }

এই ভাবে আপনি কোনো কোড যোগ করার প্রয়োজন হবে না OnModelCreateপদ্ধতি


4
আমি উভয় উপায়ে একই ব্যতিক্রম পাই।
জো স্মু

11
বিদেশী কীগুলি নির্দিষ্ট করার এটি আমার স্ট্যান্ডার্ড পদ্ধতি যা সমস্ত ক্ষেত্রে ছাড়াই কার্যকর হয় যখন কোনও সত্তায় একই ধরণের একাধিক ন্যাভ সম্পত্তি থাকে (হোমটিম এবং গেস্টিটাম দৃশ্যের অনুরূপ), সেক্ষেত্রে EF এসকিউএল তৈরির ক্ষেত্রে বিভ্রান্ত হয়। সমাধান হ'ল OnModelCreateগ্রহণযোগ্য উত্তর অনুসারে কোড যুক্ত করা এবং সম্পর্কের উভয় পক্ষের জন্য দুটি সংগ্রহ।
স্টিভেন ম্যানুয়েল

আমি উল্লিখিত কেস বাদে সকল ক্ষেত্রে অনডেলক্রিটিং ব্যবহার করি, আমি ডেটা টিকা বিশিষ্ট বিদেশী কী ব্যবহার করি, পাশাপাশি কেন জানি না এটি গৃহীত হয় না !!
হোসাম হেমালি

48

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

নীচের কোডটি পরীক্ষিত নয়।

public class Team
{
    [Key]
    public int TeamId { get; set;} 
    public string Name { get; set; }

    [InverseProperty("HomeTeam")]
    public virtual ICollection<Match> HomeMatches { get; set; }

    [InverseProperty("GuestTeam")]
    public virtual ICollection<Match> GuestMatches { get; set; }
}


public class Match
{
    [Key]
    public int MatchId { get; set; }

    public float HomePoints { get; set; }
    public float GuestPoints { get; set; }
    public DateTime Date { get; set; }

    public virtual Team HomeTeam { get; set; }
    public virtual Team GuestTeam { get; set; }
}

আপনি এমএসডিএন-তে ইনভার্সপ্রোপার্টি সম্পর্কে আরও পড়তে পারেন: https://msdn.microsoft.com/en-us/data/jj591583?f=255&MSPPError=-2147217396# সম্পর্কিত সম্পর্ক


1
এই উত্তরের জন্য ধন্যবাদ, তবে এটি বিদেশী কী কলামগুলি ম্যাচ সারণীতে nallable করে তোলে।
রবহর্ড

এটি EF 6 এ আমার পক্ষে দুর্দান্ত কাজ করেছে যেখানে nullable সংগ্রহের প্রয়োজন ছিল।
পাইন্ট

যদি আপনি সাবলীল এপিআই এড়াতে চান (যে কোনও কারণেই হোক না কেন # বিবিধ আলোচনা) এটি দুর্দান্তভাবে কাজ করে works আমার ক্ষেত্রে আমাকে "ম্যাচ" সত্তায় একটি অতিরিক্ত foriegnKey টীকা অন্তর্ভুক্ত করা দরকার, কারণ আমার ক্ষেত্র / সারণিতে পিকেটির জন্য স্ট্রিং রয়েছে।
DiscipleMichael

1
এটি আমার পক্ষে ব্যাপকভাবে কাজ করেছে। BTW। আপনি যদি কলামগুলি বাতিল করতে না চান তবে আপনি [বিদেশী কী] বৈশিষ্ট্য সহ বিদেশী কী নির্দিষ্ট করতে পারেন। কীটি যদি শুল্কযোগ্য না হয় তবে আপনি সমস্ত প্রস্তুত।
জাকুব হলভস্কি

16

আপনি এটিও চেষ্টা করে দেখতে পারেন:

public class Match
{
    [Key]
    public int MatchId { get; set; }

    [ForeignKey("HomeTeam"), Column(Order = 0)]
    public int? HomeTeamId { get; set; }
    [ForeignKey("GuestTeam"), Column(Order = 1)]
    public int? GuestTeamId { get; set; }

    public float HomePoints { get; set; }
    public float GuestPoints { get; set; }
    public DateTime Date { get; set; }

    public virtual Team HomeTeam { get; set; }
    public virtual Team GuestTeam { get; set; }
}

আপনি যখন কোনও এফকে কলামটি নুলসকে অনুমতি দেয় তখন আপনি চক্রটি ভেঙে চলে যাবেন। অথবা আমরা কেবল ইএফ স্কিমা জেনারেটরকে প্রতারণা করছি।

আমার ক্ষেত্রে, এই সাধারণ পরিবর্তনটি সমস্যার সমাধান করে।


3
পাঠকদের সাবধানতা। যদিও এটি স্কিমা সংজ্ঞা সমস্যার আশেপাশে কাজ করতে পারে, তবে এটি শব্দার্থকে পরিবর্তিত করে। দুটি দল ছাড়া ম্যাচটি হতে পারে এমন ঘটনা সম্ভবত নয়।
N8allan

14

এটি কারণ ক্যাসকেড মুছে ফেলা ডিফল্টরূপে সক্ষম করা হয়। সমস্যাটি হ'ল আপনি যখন সত্তার উপর কোনও মুছা কল করবেন, এটি প্রতিটি এফ-কী রেফারেন্সযুক্ত সত্তাও মুছে ফেলবে। এই সমস্যাটি সমাধান করার জন্য আপনার 'প্রয়োজনীয়' মানগুলি naclable করা উচিত নয়। EF কোড ফার্স্টের ক্যাসকেড মোছার কনভেনশন অপসারণ করা এর চেয়ে ভাল বিকল্প হবে:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 

ম্যাপিং / কনফিগার করার সময় বাচ্চাদের প্রত্যেকের জন্য ক্যাসকেড মোছার বিষয়টি স্পষ্টভাবে নির্দেশ করা নিরাপদ। সত্তা.


সুতরাং এটি কার্যকর করার পরে এটি কি? Restrictএর বদলে Cascade?
জো স্মু

4

InverseProperty EF কোর ইন সমাধানটিকে সহজ এবং পরিষ্কার করে তোলে।

InverseProperty

সুতরাং কাঙ্ক্ষিত সমাধানটি হ'ল:

public class Team
{
    [Key]
    public int TeamId { get; set;} 
    public string Name { get; set; }

    [InverseProperty(nameof(Match.HomeTeam))]
    public ICollection<Match> HomeMatches{ get; set; }

    [InverseProperty(nameof(Match.GuestTeam))]
    public ICollection<Match> AwayMatches{ get; set; }
}


public class Match
{
    [Key]
    public int MatchId { get; set; }

    [ForeignKey(nameof(HomeTeam)), Column(Order = 0)]
    public int HomeTeamId { get; set; }
    [ForeignKey(nameof(GuestTeam)), Column(Order = 1)]
    public int GuestTeamId { get; set; }

    public float HomePoints { get; set; }
    public float GuestPoints { get; set; }
    public DateTime Date { get; set; }

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