সত্তা কাঠামোর মধ্যে সন্নিবেশিত সত্তার আইডি আমি কীভাবে পেতে পারি? [বন্ধ]


611

Asp.net এন্টি ফ্রেমওয়ার্ক নিয়ে আমার সমস্যা আছে। আমি যখনই ডাটাবেসে কোনও বস্তু যুক্ত করি তখন আইডি মানটি পেতে চাই। কিভাবে আমি এটি করতে পারব?


16
নীচে লেডিস্লাভ মৃঙ্কার উত্তর সঠিক উত্তর, এবং এটি হিসাবে গ্রহণ করা উচিত।
CShark

3
ওপি কেবল তার / তার অ্যাকাউন্টে একবার পোস্ট করেছে, এই প্রশ্নটি আরও সুনির্দিষ্ট। এটি তাকে / তার খ্যাতিতে প্রায় 2 ক (মঞ্জুরি) দিয়েছিল, উত্তরটি গ্রহণযোগ্য বিচ হিসাবে চিহ্নিত করা হয়নি কারণ সেই দিন থেকে অ্যাকাউন্টটি পরিত্যাগ করা হয়েছে।
মুরারিএলেক্স

1
যদি কোনও বিদেশী কী সম্পর্কের জন্য এটির আইডির প্রয়োজন হয় তবে আপনি কেবলমাত্র আপনার নির্ভরশীল সত্তার নেভিগেশনাল সম্পত্তি পূর্বের যুক্ত সত্তায় সেট করতে বিবেচনা করতে পারেন। এই SaveChangesআইডিটি পেতে আপনাকে এখনই কল করার বিষয়ে মাথা ঘামানোর দরকার নেই। এখানে আরও পড়া ।
বি

সত্তা ফ্রেমওয়ার্ক কোর 3.0 এর জন্য, গ্রহণযোগ্য সমস্ত চ্যাঞ্জসঅনসাক্সেস প্যারামিটারটিকে সত্য হিসাবে যুক্ত করুন: _Contxt.SaveChangesAsync (সত্য) অপেক্ষা করুন;
মাইক

উত্তর:


1005

এটা বেশ সহজ। আপনি ব্যবহার করে থাকেন ডিবি উত্পন্ন Id গুলি (যেমন IDENTITYমাইক্রোসফট SQL এর যে) আপনি শুধু সত্তা যোগ করতে হবে ObjectSetএবং SaveChangesএর সাথে সম্পর্কিত উপর ObjectContextIdআপনার জন্য স্বয়ংক্রিয়ভাবে পূরণ করা হবে:

using (var context = new MyContext())
{
  context.MyEntities.Add(myNewObject);
  context.SaveChanges();

  int id = myNewObject.Id; // Yes it's here
}

ডিফল্টরূপে সত্তা কাঠামো প্রতিটি স্বতঃ উত্পাদিত ব্যবহৃত INSERTহয় SELECT SCOPE_IDENTITY()যখন অনুসরণ করে Id


34
সুতরাং আপনি ভুল প্রশ্ন জিজ্ঞাসা করছেন। যদি আপনার ব্যতিক্রম নিয়ে সমস্যা থাকে তবে আপনার ব্যতিক্রম (এবং অভ্যন্তরীণ ব্যতিক্রম) এবং কোড স্নিপেটটি সেই ত্রুটির কারণ দেখাচ্ছে এমন প্রশ্ন জিজ্ঞাসা করা উচিত।
লাডিস্লাভ Mrnka

3
। নিশ্চিত করুন যে সত্তা আপনাকে জুড়তে হয় একটি বৈধ সত্তা যেমন হয়, "না নাল" এর একটি ডাটাবেস সীমাবদ্ধতা নিয়ে কিছু ইত্যাদি পূরণ করা আবশ্যক
Fran

4
@ লাডিস্লাভ মির্নকা: সদ্য নির্মিত বস্তুর নেভিগেশন বৈশিষ্ট্য সম্পর্কে কী? পরিবর্তনগুলি সংরক্ষণের পরে তারা স্বয়ংক্রিয়ভাবে জনবহুল হয়ে উঠবে বলে মনে হয় না।
আইজাক ক্লেইনম্যান

4
আসুন নিম্নলিখিত পরিস্থিতিতে বিবেচনা করুন: টেবিল 1 এটি টেবিল 2 এ ব্যবহার করতে একটি @@ পরিচয় তৈরি করার কথা। টেবিল 1 এবং টেবিল 2 উভয়ই একই লেনদেনের জন্য অনুমিত হয় যেমন একটি সেভচেনজ অপারেশন উভয়েরই সারণির ডেটা সংরক্ষণ করতে হবে। 'সেভচেনজস' না নিলে @@ পরিচয় তৈরি করা হবে না। আমরা এই পরিস্থিতিটি কীভাবে মোকাবেলা করতে পারি?
আরশ

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

123

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

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

var customer = new Customer(); //no Id yet;
var order = new Order(); //requires Customer.Id to link it to customer;
context.Customers.Add(customer);
context.SaveChanges();//this generates the Id for customer
order.CustomerId = customer.Id;//finally I can set the Id

তবে আমার ক্ষেত্রে এটির প্রয়োজন ছিল না কারণ গ্রাহকআইআরআইড এবং অর্ডার-কাস্টমারের আইডির মধ্যে আমার একটি বিদেশী কী সম্পর্ক ছিল

আমাকে যা করতে হয়েছিল তা হ'ল;

var customer = new Customer(); //no Id yet;
var order = new Order{Customer = customer}; 
context.SaveChanges();//adds customer.Id to customer and the correct CustomerId to order

এখন আমি যখন পরিবর্তনগুলি সংরক্ষণ করি তখন গ্রাহকের জন্য তৈরি করা আইডিটিও অর্ডার যুক্ত করা হয়। আমার অতিরিক্ত পদক্ষেপের দরকার নেই

আমি জানি যে এটি আসল প্রশ্নের উত্তর দেয় না তবে ভেবেছিল যে এটি এমন বিকাশকারীদের সাহায্য করতে পারে যা EF তে নতুন যারা উচ্চ প্রয়োজনে এমন উত্তরের জন্য অতিরিক্ত ভোটের উত্তরটি ব্যবহার করতে পারে না যা প্রয়োজন হয় না।

এর অর্থ হ'ল আপডেটগুলি একক লেনদেনে সম্পূর্ণ হয়, সম্ভাব্যভাবে অরফিন ডেটা এড়ানো হয় (হয় সমস্ত আপডেট সম্পূর্ণ হয়, না কিছুই হয়)।


8
ধন্যবাদ! গুরুত্বপূর্ণ সর্বোত্তম অনুশীলনের টিপ: var অর্ডার = নতুন অর্ডার {গ্রাহক = গ্রাহক}; এটি সম্পর্কিত অবজেক্ট বরাদ্দ করার জন্য সত্তা ফ্রেমওয়ার্কের শক্তি দেখায় এবং আইডি স্বয়ংক্রিয়ভাবে আপডেট হবে।
এল এ গাই 88

উত্তরের এই অতিরিক্ত তথ্যের জন্য ধন্যবাদ। EF ব্যবহার করার সময় একটি ডিবি রাউন্ডট্রিপ সংরক্ষণে খুব সহায়ক ছিল।
প্রসাদ কোরহলে

এই জন্য আপনাকে অনেক ধন্যবাদ. আমি ঠিক এটিই খুঁজছিলাম। আমি কেবল বিশ্বাস করেছিলাম "সেভচেন্জেস" দু'বার কল করার চেয়ে আরও ভাল উপায় আর হতে পারে
জোশ

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

32

পরিবর্তনগুলি সংরক্ষণের পরে আপনাকে সত্তাটি পুনরায় লোড করা দরকার। কারণ এটি একটি ডাটাবেস ট্রিগার দ্বারা পরিবর্তিত হয়েছে যা ইএফ দ্বারা ট্র্যাক করা যায় না। সুতরাং আমাদের সত্তাকে আবার ডিবি থেকে পুনরায় লোড করা দরকার,

db.Entry(MyNewObject).GetDatabaseValues();

তারপর

int id = myNewObject.Id;

নীচের প্রশ্নের @ জয়ন্তের উত্তরটি দেখুন:

ডিফল্টভ্যালু ব্যবহার করার সময় সত্তা কাঠামোর মধ্যে সন্নিবেশিত সত্তার আইডি আমি কীভাবে পেতে পারি?

নীচে প্রশ্নের উত্তর ক্রিশ্চিয়ানের উত্তর খুঁজছেন এছাড়াও সাহায্য করতে পারে:

সত্তা ফ্রেমওয়ার্ক রিফ্রেশ প্রসঙ্গে?


2
হাই, যখন আমি এটি করি, তখন আমি সংকলন ত্রুটি পেয়েছি যা বলে: উদাহরণস্বরূপ আইডি বা নামের বৈশিষ্ট্যগুলি সমাধান করতে পারে না, আপনি আমাকে দয়া করে সহায়তা করতে পারেন?
মরতেজা আজিজি

1
@ মোর্তেজাআজিজি এটি সম্পত্তি পরিচালনা বা নালীর সমস্যা নয় বলে ত্রুটি বলে মনে হচ্ছে তবে আপনি কি দয়া করে কোডের কিছু স্নিপেট আরও ব্যাখ্যা বা লিখতে পারেন?
কিউমাস্টার

3
.GetDatabaseValues();আপনি যদি কেবলমাত্র আপনার মডেলটি ডিবি-তে সংরক্ষণ করেন তবে তা করার দরকার নেই । আইডিটি স্বয়ংক্রিয়ভাবে মডেলটিতে পুনরায় প্রকাশ করা উচিত।
vapcguy

3
@ কিমিস্টার ব্যতীত EF এছাড়াও সেই একই এসকিউএল স্টেটমেন্ট কার্যকর করতে সক্ষম (এবং করবে) এবং আপনার অবজেক্টের আইডি পপুলেট করে। অন্যথায়, এটি একই সাথে একাধিক নির্ভরশীল অবজেক্টগুলিকে কীভাবে সংরক্ষণ করতে সক্ষম? এটি কীভাবে সক্ষম হবে GetDatabaseValues()যদি এটি ডাটাবেসে অনুসন্ধান করার জন্য অবজেক্টটির আইডি না জানত?
ক্রিলগার

2
@ Vapcguy- কে দেখতে পাচ্ছি। আপনার মনের জন্য ধন্যবাদ আমি EF উভয় সংস্করণে এটি ASAP যাচাই করব।
কিউমাস্টার

16

এই লিঙ্কটি উল্লেখ করুন।

http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/

আপনাকে স্টোরজেনেটেড প্যাটার্নের সম্পত্তি পরিচয় হিসাবে সেট করতে হবে এবং তারপরে আপনার নিজের কোডটি চেষ্টা করতে হবে।

অন্যথায় আপনি এটি ব্যবহার করতে পারেন।

using (var context = new MyContext())
{
  context.MyEntities.AddObject(myNewObject);
  context.SaveChanges();

  int id = myNewObject.Id; // Your Identity column ID
}

7
শীর্ষ ভোট দেওয়া উত্তর হিসাবে একই।
লুইস 86

2
StoreGeneratedPatternআমার জন্য অনুপস্থিত অংশ ছিল।
বার্নসবিএ

1
ORACLE এবং অন-Trোকান ট্রিগারটির সাথে কাজ করার সময় এটিই যেতে পারে
কার্ল

লিঙ্কটি ভাঙ্গা - পার্কযুক্ত ডোমেন
t.durden

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

15

আপনি যে জিনিসটি সংরক্ষণ করছেন Idতা ডাটাবেসে পরিবর্তন প্রচারের পরে একটি সঠিক হওয়া উচিত ।


27
আপনি কি ভিতরের ব্যতিক্রম দেখেছেন? ;-)
স্নোবিয়ার

6

আপনি কেবল সংরক্ষণের পরে আইডি পেতে পারেন, পরিবর্তে আপনি একটি নতুন গাইড তৈরি করতে পারেন এবং সংরক্ষণের আগে নির্ধারিত করতে পারেন।


4

আমি এমন একটি পরিস্থিতি নিয়ে এসেছি যেখানে আমাকে ডাটাবেসে ডেটা inোকানো প্রয়োজন এবং একই সাথে সত্তা ফ্রেমওয়ার্ক ব্যবহার করে প্রাথমিক আইডি প্রয়োজন। সমাধান:

long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
 {
    InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
    InfoBase.Add(generalinfo);
    InfoBase.Context.SaveChanges();
    id = entityclassobj.ID;
    return id;
 }

4

সমস্ত উত্তরগুলি তাদের নিজস্ব দৃশ্যের জন্য খুব উপযুক্ত;

using (Entities entities = new Entities())
{
      int employeeId = entities.Employee.Add(new Employee
                        {
                            EmployeeName = employeeComplexModel.EmployeeName,
                            EmployeeCreatedDate = DateTime.Now,
                            EmployeeUpdatedDate = DateTime.Now,
                            EmployeeStatus = true
                        }).EmployeeId;

      //...use id for other work
}

সুতরাং সম্পূর্ণ নতুন অবজেক্ট তৈরির পরিবর্তে, আপনি যা চান কেবল তা গ্রহণ করুন :)

মিঃ @ গার্টআরনল্ডের জন্য সম্পাদনা করুন:

এখানে চিত্র বর্ণনা লিখুন


3
কোনও আইডি বরাদ্দের জন্য প্রকাশ-অ-প্রকাশিত পদ্ধতি যুক্ত করা সত্যিই কার্যকর নয়। এটি এমনকি সত্তা ফ্রেমওয়ার্কের সাথে সম্পর্কিত নয়।
গার্ট আর্নল্ড

1
@ গ্রেটআরনল্ড .. আমার ওপি-র মত একই প্রশ্ন ছিল আমি উত্তরগুলি পেয়েছি এবং এটিকে একটি একক লাইন বিবৃতিতে পরিণত করেছি, এবং আমি ব্যাখ্যা করার জন্য অ-প্রকাশিত পদ্ধতি যত্ন শব্দটি কখনও শুনিনি ?
আইট্রেটিওএন

3
এর অর্থ হ'ল আপনি যা কিছু করেন তা আপনি প্রকাশ (প্রকাশ) করবেন না। সম্ভবত এটি কেবল পরিষ্কারভাবে বর্ণিত নয়, আমি জানি না। আমি যা জানি তা হ'ল Add(যদি এটি হয় DbSet.Add) যাদুকরীতে কোনও মান নির্ধারণ করে নাEmployeeId
গার্ট আর্নল্ড

3
ছাড়া না SaveChanges। অসম্ভব। আপনার যদি অন্য কোনও প্রক্রিয়া নির্ধারিত EmployeeIdনা হয় তবে উদাহরণস্বরূপ Employeeএর কনস্ট্রাক্টর। অথবা আপনি EF কোর ব্যবহার করছেন ForSqlServerUseSequenceHiLo। যাইহোক, আপনি পুরো ছবি দিচ্ছেন না।
গার্ট আর্নল্ড

3
আমার শেষ মন্তব্যটি হবে: এটি স্ট্যান্ডার্ড EF আচরণ নয়। আপনার আপনার পরিবেশের আরও বিশদ দেওয়া উচিত। EF সংস্করণ, ডাটাবেস ব্র্যান্ড এবং সংস্করণ, কর্মী শ্রেণি, এর ম্যাপিংয়ের বিশদ।
গার্ট আর্নল্ড

3
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;

এটি কাজ করবে।


4
সংরক্ষণাগার ডাটাবেসে পরিবর্তনগুলি সংরক্ষণের জন্য দায়ী নয়। এটি ইউনিটঅফ ওয়ার্কের কাজ।
tchelidze

5
তদুপরি, এটি কি Repositoryতা সম্পূর্ণ অস্পষ্ট । এবং "এটি কাজ করবে" এর কিছু ব্যাখ্যা !.
গার্ট আর্নল্ড

2

দুটি কৌশল রয়েছে:

  1. ডেটাবেস-উত্পন্ন ID( intবা GUID) ব্যবহার করুন

    কনস:

    সবেমাত্র সঞ্চিত সত্তাদের জন্য আপনার সম্পাদন SaveChanges()করা উচিত ID

    পেশাদাররা:

    intপরিচয় ব্যবহার করতে পারেন ।

  2. উত্পন্ন ক্লায়েন্ট ব্যবহার করুন ID- কেবল জিইউডি।

    পেশাদাররা: SaveChangesঅপারেশন মিনিফিকেশন । প্রতি ক্রিয়াকলাপে নতুন অবজেক্টের একটি বড় গ্রাফ toোকাতে সক্ষম।

    কনস:

    শুধুমাত্র জন্য অনুমোদিত GUID


1

আপনি যখন EF 6.x কোডটি প্রথমে ব্যবহার করবেন

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

এবং একটি ডাটাবেস টেবিল সূচনা, এটি একটি করা হবে

(newsequentialid())

শিরোনাম ডিফল্ট মান বা বাঁধার অধীনে সারণীর বৈশিষ্ট্যগুলির ভিতরে আইডি asোকানো হিসাবে পপুলেট হতে দেয়।

সমস্যাটি হ'ল যদি আপনি কোনও টেবিল তৈরি করেন এবং এটি যোগ করুন

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

অংশটি পরে, ভবিষ্যতের আপডেট-ডাটাবেসগুলি নতুন (নতুন প্রয়োজনীয়) () যুক্ত করবে না

সঠিক উপায়টি স্থির করার জন্য হ'ল মাইগ্রেশন মুছা, ডাটাবেস মুছে ফেলা এবং পুনরায় স্থানান্তর করা ... বা আপনি কেবল সারণি ডিজাইনারে (newsequentialid ()) যুক্ত করতে পারেন।


নতুন সিক্যুয়েন্সিড () কোথায় যায় সে সম্পর্কে আপনি কী বিশদ বর্ণনা করতে পারেন? আমার কাছে ইতিমধ্যে ইএফ কোডটি ব্যবহার না করে হাতে হাতে তৈরি করা ডেটাবেস মডেল রয়েছে এবং এটি আমার প্রাথমিক কী নয় বলে আইডিটি পূরণ করে না। এর সমাধান খুঁজে পেতে পছন্দ করবেন।
জোশ

1
@ জোশ কোডটি ধরে নিচ্ছেন প্রথমে গাইডের ধরণ, এসকিউএল সার্ভার ম্যানেজমেন্ট স্টুডিওতে আপনার টেবিলটিতে ডান ক্লিক করুন, আইডি কলামটি ক্লিক করুন, এবং (সাধারণ) কলাম বৈশিষ্ট্য ট্যাবটির নীচে আপনি ডিফল্ট মান বা বাঁধাই দেখতে পাবেন। আপনি যদি হাতে ডিবি টেবিল তৈরি করে থাকেন তবে নিউ সেকুয়েন্সিয়ালআইডি বা নিউআইডি পড়ুন । সাধারণ ব্যবহারের ক্ষেত্রে ভালো কিছু হয়when -column- is NULL, then NEWID()
জেফ লি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.