এমভিসি 3 তে কোড ফার্স্ট সত্তা ফ্রেমওয়ার্ক (4.1) ব্যবহার করে কীভাবে আমি বিদেশী কী সম্পর্ক ঘোষণা করব?


104

আমি কীভাবে অনেক ভাগ্য ছাড়াই প্রথম EF 4.1 কোড ব্যবহার করে বিদেশী কী সম্পর্ক এবং অন্যান্য প্রতিবন্ধকতাগুলি ঘোষণা করতে পারি সে সম্পর্কিত সংস্থানগুলি অনুসন্ধান করছি। মূলত আমি কোডে ডেটা মডেলটি তৈরি করছি এবং সেই মডেলটিকে জিজ্ঞাসা করতে এমভিসি 3 ব্যবহার করছি। এমভিসি এর মাধ্যমে সমস্ত কিছু কাজ করে যা দুর্দান্ত (মাইক্রোসফ্টের কাছে কুডোস!) তবে এখন আমি এটি কাজ না করা চাই কারণ আমার কাছে ডেটা মডেলের সীমাবদ্ধতা থাকা দরকার।

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

আমি বুঝতে পারি যে সংরক্ষণ করার আগে আমি কেবলমাত্র নিয়ামক শ্রেণিতে নিজেকে বস্তুগুলি যুক্ত করতে পারতাম, তবে আমি চাই ডিবিকন্টেক্সটকে কল করুন han সেভচেনজেস () সীমাবদ্ধতার সম্পর্কগুলি পূরণ না করা হলে ব্যর্থ হওয়ার জন্য।

নতুন তথ্য

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

সর্বশেষ কোড:

public class Order
{
    public int Id { get; set; }

    [ForeignKey( "Parent" )]
    public Patient Patient { get; set; }

    [ForeignKey("CertificationPeriod")]
    public CertificationPeriod CertificationPeriod { get; set; }

    [ForeignKey("Agency")]
    public Agency Agency { get; set; }

    [ForeignKey("Diagnosis")]
    public Diagnosis PrimaryDiagnosis { get; set; }

    [ForeignKey("OrderApprovalStatus")]
    public OrderApprovalStatus ApprovalStatus { get; set; }

    [ForeignKey("User")]
    public User User { get; set; }

    [ForeignKey("User")]
    public User Submitter { get; set; }

    public DateTime ApprovalDate { get; set; }
    public DateTime SubmittedDate { get; set; }
    public Boolean IsDeprecated { get; set; }
}

রোগীর জন্য ভিএস উত্পন্ন ভিউ অ্যাক্সেস করার সময় আমি এখন এই ত্রুটিটি পেয়েছি:

ভুল বার্তা

'ফিজিশিয়ানপোর্টাল.মোডেলস.অর্ডার' টাইপ করে সম্পত্তি 'রোগী' সম্পর্কিত ফরেনকিঅ্যাট্রিবিউট বৈধ নয়। নির্ভরযোগ্য টাইপ 'ফিজিশিয়ানপোর্টাল.মোডেলস.আর্ডার' তে বিদেশী কী নাম 'প্যারেন্ট' পাওয়া যায়নি। নামের মানটি বিদেশী কী সম্পত্তি নামগুলির কমা দ্বারা পৃথক হওয়া তালিকা হওয়া উচিত।

শুভেচ্ছা সহ,

গাইডো

উত্তর:


164

আপনার যদি কোনও Orderশ্রেণি থাকে, এমন একটি সম্পত্তি যুক্ত করে যা আপনার মডেলটিতে অন্য শ্রেণির উল্লেখ করে, উদাহরণস্বরূপ CustomerEF কে জানাতে যথেষ্ট হবে যে সেখানে কোনও সম্পর্ক রয়েছে:

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    public virtual Customer Customer { get; set; }
}

আপনি সর্বদা FKস্পষ্টভাবে সম্পর্ক সেট করতে পারেন :

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    [ForeignKey("Customer")]
    public string CustomerID { get; set; }
    public virtual Customer Customer { get; set; }
}

দ্য ForeignKeyAttributeকন্সট্রাকটর প্যারামিটার হিসেবে একটি স্ট্রিং লাগে যদি আপনি একটি বিদেশী কী সম্পত্তি রাখুন এটা সংশ্লিষ্ট গৌণ সম্পত্তির নাম প্রতিনিধিত্ব করে। আপনি এটিকে নেভিগেশন সম্পত্তি এ রাখলে এটি সম্পর্কিত বিদেশী কীটির নাম উপস্থাপন করে।

এর অর্থ কী, আপনি যদি সম্পত্তিটির ForeignKeyAttributeউপরে কোথায় রাখবেন Customer, গুণটি CustomerIDকনস্ট্রাক্টরের মধ্যে নিতে হবে :

public string CustomerID { get; set; }
[ForeignKey("CustomerID")]
public virtual Customer Customer { get; set; }

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

[ForeignKey("Parent")]
public Patient Patient { get; set; }

EF নামক কোনও সম্পত্তি খুঁজবে Parent বিদেশী কী প্রয়োগকারী হিসাবে এটি ব্যবহার করার জন্য । আপনি 2 টি জিনিস করতে পারেন:

1) অপসারণ করুন ForeignKeyAttributeএবং এটি RequiredAttributeপ্রয়োজনীয় হিসাবে সম্পর্ক চিহ্নিত করতে এটির সাথে প্রতিস্থাপন করুন :

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

এর সাথে একটি সম্পত্তি সাজাতেও একটি দুর্দান্ত RequiredAttributeপার্শ্ব প্রতিক্রিয়া হয়: ডাটাবেসের সাথে সম্পর্ক তৈরি হয় ON DELETE CASCADE

virtualঅলস লোডিং সক্ষম করার জন্য আমি সম্পত্তিটি তৈরি করার পরামর্শ দেব ।

2) Parentএকটি বিদেশী কী হিসাবে কাজ করবে এমন একটি সম্পত্তি তৈরি করুন । ParentIDসেক্ষেত্রে সম্ভবত এটির কল করা আরও বোধগম্য হয় (আপনার ForeignKeyAttributeপাশাপাশি নামটিও পরিবর্তন করতে হবে ):

public int ParentID { get; set; }

আমার ক্ষেত্রে এই ক্ষেত্রে যদিও এটি অন্যান্য উপায়ে আরও ভালভাবে কাজ করে:

[ForeignKey("Patient")]
public int ParentID { get; set; }

public virtual Patient Patient { get; set; }

ধন্যবাদ সের্গি - আমি ব্লক উদ্ধৃতিতে কিছু অতিরিক্ত তথ্য যুক্ত করেছি।
গুইডো আনসেলমি

@ গুয়েডো - আমি আপনার সর্বশেষ কোড সম্পাদনার ভিত্তিতে আমার উত্তর আপডেট করেছি, আশা করি এটি সাহায্য করবে।
সের্গি পাপাসিট

30

আপনি বিদেশী কী দ্বারা এটি সংজ্ঞায়িত করতে পারেন:

public class Parent
{
   public int Id { get; set; }
   public virtual ICollection<Child> Childs { get; set; }
}

public class Child
{
   public int Id { get; set; }
   // This will be recognized as FK by NavigationPropertyNameForeignKeyDiscoveryConvention
   public int ParentId { get; set; } 
   public virtual Parent Parent { get; set; }
}

এখন প্যারেন্টআইডি হ'ল বিদেশী কী সম্পত্তি এবং শিশু এবং বিদ্যমান পিতামাতার মধ্যে প্রয়োজনীয় সম্পর্কটিকে সংজ্ঞায়িত করে। পিতামাতাকে ছাড়িয়ে না রেখে শিশুকে বাঁচানো ব্যতিক্রম ছুঁড়ে দেবে।

যদি আপনার এফ কে সম্পত্তি নামটিতে নেভিগেশন সম্পত্তির নাম এবং পিতামাতার পিকে নাম না থাকে তবে আপনাকে অবশ্যই সম্পর্কের মানচিত্রের জন্য বিদেশীকিঅ্যাট্রিবিউটের ডেটা টীকা বা সাবলীল এপিআই ব্যবহার করতে হবে

ডেটা টিকা:

// The name of related navigation property
[ForeignKey("Parent")]
public int ParentId { get; set; }

সাবলীল এপিআই:

modelBuilder.Entity<Child>()
            .HasRequired(c => c.Parent)
            .WithMany(p => p.Childs)
            .HasForeignKey(c => c.ParentId);

অন্যান্য ধরণের সীমাবদ্ধতা ডেটা টিকা এবং মডেল বৈধতা দ্বারা প্রয়োগ করা যেতে পারে ।

সম্পাদনা:

আপনি সেট না করলে আপনি ব্যতিক্রম পাবেন ParentId। এটি প্রয়োজনীয় সম্পত্তি (নমনীয় নয়)। আপনি যদি এটি সেট না করেন তবে এটি সম্ভবত ডাটাবেসে ডিফল্ট মান প্রেরণের চেষ্টা করবে। ডিফল্ট মান 0 হয় তাই আপনার আইডি = 0 সহ গ্রাহক না থাকলে আপনি একটি ব্যতিক্রম পাবেন।


ধন্যবাদ লাদিস্লাভ - আমি ব্লক উদ্ধৃতিতে কিছু অতিরিক্ত তথ্য যুক্ত করেছি।
গুইডো আনসেলমি

@Ladislav। সুতরাং এই সীমাবদ্ধতাটি প্রয়োগ করার জন্য আমার পিতামাতার উল্লেখ এবং প্যারেন্টআইডের একটি রেফারেন্স উভয়ই রাখতে হবে। এটা কি ঠিক? আমি রেফারেন্সের জন্য উপরের আসল ক্লাসটি যুক্ত করব।
গুইডো আনসেলমি

@ গুয়েডো: এটিই নতুন তথ্য। আপনি বিদেশী কী বৈশিষ্ট্য ব্যবহার করছেন না। আপনার সমস্ত নেভিগেশন বৈশিষ্ট্যগুলি ডিফল্টরূপে asচ্ছিক হিসাবে পরিচালনা করা হয়। প্রয়োজনীয় হিসাবে তাদের মানচিত্র করতে সাবলীল ম্যাপিং ব্যবহার করুন।
লাদিস্লাভ Mrnka

@ লাডিস্লাভ: আপনাকে আবারও ধন্যবাদ ডেটা টিকা এবং ফ্লুয়েন্ট এপিআই ব্যবহারের মধ্যে পার্থক্য বুঝতে আমি প্রায় ঘুরে দেখছি। আপনি যা বলছেন বলে আমি মনে করি তার সাথে সামঞ্জস্য রেখে আমি উপরের কোডটিতে পরিবর্তন করেছি। উপরের সব কি আমাকে করতে হবে? শুভেচ্ছা।
গাইডো আনসেলমি

কোনও বিদেশীকি বৈশিষ্ট্য বিদেশী কী সম্পত্তি বা তদ্বিপরীত সম্পর্কিত নেভিগেশন সম্পত্তি সংজ্ঞা দেয় না। আপনার কাছে বিদেশী কী বৈশিষ্ট্য নেই তাই আপনি এই বৈশিষ্ট্যটি ব্যবহার করতে পারবেন না। আপনার নেভিগেশন বৈশিষ্ট্যে প্রয়োজনীয় বৈশিষ্ট্যটি ব্যবহার করার চেষ্টা করুন (আমি এটি পরীক্ষা করে দেখিনি)।
লাডিস্লাভ মৃঙ্কা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.