ওয়েব প্রতি অনুরোধের জন্য একটি ডিবি কনটেক্সট ... কেন?


398

সত্তা ফ্রেমওয়ার্ক কীভাবে সেট আপ করবেন সে সম্পর্কে আমি অনেক নিবন্ধ পড়ছি DbContextযা এইচটিটিপি ওয়েব অনুরোধে বিভিন্ন ডিআই ফ্রেমওয়ার্ক ব্যবহার করে কেবল একটি তৈরি করা হয়।

এটি কেন প্রথম স্থানে একটি ভাল ধারণা? এই পদ্ধতির ব্যবহার করে আপনি কী সুবিধা অর্জন করবেন? এমন কিছু পরিস্থিতি রয়েছে যেখানে এটি একটি ভাল ধারণা হবে? এমন কিছু জিনিস রয়েছে যা আপনি এই কৌশলটি ব্যবহার করে করতে পারেন যা আপনি DbContextপ্রতিস্থাপনের পদ্ধতিতে কল প্রতি ইনস্ট্যান্ট করার সময় করতে পারবেন না ?


9
Mehdi.me/ambient-dbcontext-in-ef6- তে গুয়াদারী ডিপো কনটেক্সট ইনস্ট্যান্স প্রতি সংগ্রহের পদ্ধতি অনুসারে একটি অ্যান্টিপ্যাটার্ন কল করে। উদ্ধৃতি: "এটি করার মাধ্যমে আপনি সত্তা ফ্রেমওয়ার্ক তার প্রথম স্তরের ক্যাশে, এটির পরিচয় মানচিত্র, তার ইউনিট-অফ-ওয়ার্ক এবং তার পরিবর্তন ট্র্যাকিং এবং অলস-লোডিং ক্ষমতা সহ DbContext এর মাধ্যমে সরবরাহ করে এমন প্রতিটি বৈশিষ্ট্য হারিয়ে ফেলছেন feature । " DBContexts এর জীবনচক্র পরিচালনা করার জন্য দুর্দান্ত পরামর্শ সহ দুর্দান্ত নিবন্ধ। অবশ্যই পড়া মূল্যবান।
ক্রিস্টোফ

উত্তর:


564

দ্রষ্টব্য: এই উত্তরটি সত্তা ফ্রেমওয়ার্ক সম্পর্কে আলোচনা করে DbContextতবে এটি কার্যকরীকরণের যে কোনও ইউনিট যেমন এসকিউএল এর DataContextলিনকিউ এবং এনএইচবারনেটের ক্ষেত্রে প্রযোজ্য ISession

ইয়ান প্রতিধ্বনি দিয়ে শুরু করা যাক: DbContextপুরো অ্যাপ্লিকেশনটির জন্য একটি একক থাকা খারাপ ধারণা। আপনি যখন একটি একক থ্রেডযুক্ত অ্যাপ্লিকেশন এবং ডেটাবেসগুলি সম্পূর্ণরূপে সেই একক অ্যাপ্লিকেশন উদাহরণ দ্বারা ব্যবহার করেন তখন এটি কেবল তখনই বোঝা যায়। DbContextথ্রেড-নিরাপদ এবং নয় এবং যেহেতু DbContextক্যাশে ডেটা, এটা মামুলি বেশ তাড়াতাড়ি পায়। একাধিক ব্যবহারকারী / অ্যাপ্লিকেশনগুলি সেই ডাটাবেসে একসাথে কাজ করার সময় এটি (যা অবশ্যই খুব সাধারণ) আপনি সমস্ত প্রকার সমস্যায় পড়বেন। তবে আমি আশা করি আপনি এটি ইতিমধ্যে জেনে গেছেন এবং কেবল এটি কেন জানতে চান যে প্রয়োজনের যে কোনও ব্যক্তির মধ্যে একটি নতুন উদাহরণ (অর্থাত্ একটি ক্ষণস্থায়ী জীবনধারা সহ) কেন ইনজেক্ট করবেন DbContextনা। (কেন DbContextপ্রতিটি থ্রেড প্রসঙ্গে একটি একক -অন কেন খারাপ তা সম্পর্কে আরও তথ্যের জন্য , এই উত্তরটি পড়ুন )।

আমাকে এই বলে শুরু করে চলুন যে DbContextক্ষণস্থায়ী হিসাবে নিবন্ধকরণ কাজ করতে পারে তবে সাধারণত আপনি নির্দিষ্ট ক্ষেত্রের মধ্যে এই জাতীয় ইউনিটের কাজের একক উদাহরণ থাকতে চান। একটি ওয়েব অ্যাপ্লিকেশনটিতে, এটি একটি ওয়েব অনুরোধের সীমানায় যেমন একটি সুযোগকে সংজ্ঞায়িত করা ব্যবহারিক হতে পারে; এইভাবে প্রতি ওয়েব অনুরোধ জীবনধারা। এটি আপনাকে একই প্রসঙ্গে বস্তুর পুরো সেটটি পরিচালনা করতে দেয়। অন্য কথায়, তারা একই ব্যবসায়িক লেনদেনের মধ্যে পরিচালনা করে।

একই প্রসঙ্গে যদি আপনার কোনও সেট অপারেশন পরিচালনার কোনও লক্ষ্য না থাকে তবে সেক্ষেত্রে ক্ষণস্থায়ী জীবনধারা ভাল, তবে দেখার মতো কয়েকটি বিষয় রয়েছে:

  • যেহেতু প্রতিটি বস্তুর নিজস্ব উদাহরণ পাওয়া যায়, প্রতিটি শ্রেণি যা সিস্টেমের অবস্থার পরিবর্তন করে, তাদের কল করতে হবে _context.SaveChanges()(অন্যথায় পরিবর্তনগুলি হারিয়ে যাবে)। এটি আপনার কোডকে জটিল করে তুলতে পারে এবং কোডে একটি দ্বিতীয় দায়িত্ব যুক্ত করে (প্রসঙ্গ নিয়ন্ত্রণের দায়িত্ব), এবং এটি একক দায়িত্বের নীতি লঙ্ঘন ।
  • আপনাকে নিশ্চিত করতে হবে যে সত্ত্বাগুলি [একটি দ্বারা বোঝা এবং সংরক্ষণ করা DbContext] কখনই এই ধরণের শ্রেণির সুযোগ ছেড়ে যায় না, কারণ সেগুলি অন্য শ্রেণীর প্রসঙ্গে দেখা যায় না। এটি আপনার কোডটিকে অত্যন্ত জটিল করে তুলতে পারে, কারণ যখন আপনাকে এই সত্তাগুলির প্রয়োজন হয় তখন আপনাকে আবার আইডি দিয়ে এগুলি লোড করা দরকার যা পারফরম্যান্সেও সমস্যা তৈরি করতে পারে।
  • যেহেতু DbContextকার্যকরী IDisposable, আপনি সম্ভবত এখনও পর্যন্ত সব নির্মিত দৃষ্টান্ত নষ্ট করতে চাই। আপনি যদি এটি করতে চান তবে আপনার কাছে মূলত দুটি বিকল্প রয়েছে। কল করার পরে আপনাকে সেগুলি একই পদ্ধতিতে নিষ্পত্তি করতে হবে context.SaveChanges(), তবে সেই ক্ষেত্রে ব্যবসায়ের যুক্তি এমন কোনও বস্তুর মালিকানা নেয় যা বাইরে থেকে পাস করা হয়। দ্বিতীয় বিকল্পটি হ'ল এইচটিটিপি অনুরোধের সীমানায় তৈরি হওয়া সমস্ত দৃষ্টান্তগুলি নিষ্পত্তি করা, তবে সেই ক্ষেত্রে সেই সমস্ত দৃষ্টিকোণগুলি নিষ্পত্তি করার দরকার পরে কনটেইনারটি আপনাকে জানাতে কিছু ধরণের স্কোপিং প্রয়োজন।

আরেকটি বিকল্প হ'ল একেবারে ইনজেক্ট না করাDbContext । পরিবর্তে, আপনি DbContextFactoryএমন একটি ইনজেকশন করুন যা একটি নতুন উদাহরণ তৈরি করতে সক্ষম হয় (আমি আগে এই পদ্ধতির ব্যবহার করতাম)। এইভাবে ব্যবসায়ের যুক্তি প্রসঙ্গে সুস্পষ্টভাবে নিয়ন্ত্রণ করে। যদি দেখতে এই মত হতে পারে:

public void SomeOperation()
{
    using (var context = this.contextFactory.CreateNew())
    {
        var entities = this.otherDependency.Operate(
            context, "some value");

        context.Entities.InsertOnSubmit(entities);

        context.SaveChanges();
    }
}

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

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

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

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

ধারকটিকে এবং / অথবা অবকাঠামোটি এটি পরিচালনা করতে দেয়, আপনার অ্যাপ্লিকেশন কোডটি একটি ইউওডাব্লু ইভেন্ট তৈরি করতে (allyচ্ছিকভাবে) প্রতিশ্রুতিবদ্ধ এবং নিষ্পত্তি করে দূষিত হয় না যা ব্যবসায়ের যুক্তিটিকে সহজ এবং পরিষ্কার রাখে (কেবলমাত্র একটি একক দায়িত্ব)। এই পদ্ধতির সাথে কিছু অসুবিধা রয়েছে। উদাহরণস্বরূপ, আপনি কি প্রতিশ্রুতিবদ্ধ এবং উদাহরণটি নিষ্পত্তি করেছেন?

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

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

class TransactionalCommandHandlerDecorator<TCommand>
    : ICommandHandler<TCommand>
{
    readonly DbContext context;
    readonly ICommandHandler<TCommand> decorated;

    public TransactionCommandHandlerDecorator(
        DbContext context,
        ICommandHandler<TCommand> decorated)
    {
        this.context = context;
        this.decorated = decorated;
    }

    public void Handle(TCommand command)
    {
        this.decorated.Handle(command);

        context.SaveChanges();
    } 
}

এটি নিশ্চিত করে যে আপনার একবার এই পরিকাঠামো কোডটি লিখতে হবে। যে কোনও দৃ solid় ডিআই কনটেইনার আপনাকে এই জাতীয় ডেকরেটরকে ICommandHandler<T>একটি সুসংগত পদ্ধতিতে সমস্ত প্রয়োগের চারপাশে মোড়কে কনফিগার করতে দেয় ।


2
বাহ - পুরো উত্তরের জন্য ধন্যবাদ। আমি যদি দুবার upvote করতে পারে, আমি। উপরে, আপনি বলেছেন "... একই প্রসঙ্গে অভ্যন্তরের পুরো সেটটি পরিচালনা করার কোনও ইচ্ছা নেই, সেই ক্ষেত্রে ক্ষণস্থায়ী জীবনধারা ঠিক আছে ..."। বিশেষ করে "ক্ষণস্থায়ী" বলতে কী বোঝ?
অ্যান্ড্রু

14
@ অ্যান্ড্রু: 'ট্রান্সিয়েন্ট' হ'ল নির্ভরতা ইনজেকশন ধারণা, যার অর্থ যদি কোনও পরিষেবা ক্ষণস্থায়ী হিসাবে কনফিগার করা থাকে তবে প্রতিবারই এটি গ্রাহককে ইনজেকশনের পরে পরিষেবার একটি নতুন উদাহরণ তৈরি করা হবে।
স্টিভেন

1
@ ব্যবহারকারী981375: সিআরইউডি অপারেশনের জন্য আপনি জেনেরিক CreateCommand<TEnity>এবং জেনেরিক তৈরি করতে পারেন CreateCommandHandler<TEntity> : ICommandHandler<CreateCommand<TEntity>>(এবং আপডেট এবং মুছার জন্য একই কাজ করুন এবং আপনার একক প্রশ্নও ছিল GetByIdQuery<TEntity>)। তবুও, আপনার নিজেকে জিজ্ঞাসা করা উচিত যে এই মডেলটি CRUD অপারেশনগুলির জন্য দরকারী বিমূর্ততা, বা এটি কেবল জটিলতা যুক্ত করেছে কিনা। তবুও, আপনি এই মডেলটি ব্যবহার করে সহজেই ক্রস-কাটিং উদ্বেগগুলি (সজ্জকের মাধ্যমে) যুক্ত করার সম্ভাবনাটি থেকে উপকৃত হতে পারেন। আপনাকে উপকারিতা এবং কনসগুলি ওজন করতে হবে।
স্টিভেন

3
+1 আপনি কি বিশ্বাস করবেন যে আমি আসলে এইটি পড়ার আগে এই উত্তরটি লিখেছিলাম ? বিটিডাব্লু আইএমও আমি মনে করি আপনার শেষে DbContext নিষ্পত্তি নিয়ে আলোচনা করা গুরুত্বপূর্ণ (যদিও এটি দুর্দান্ত যে আপনি ধারক
অজ্ঞেয় রয়েছেন

1
তবে আপনি প্রসঙ্গে সাজানো ক্লাসে প্রসঙ্গটি পাস করবেন না, সজ্জিত শ্রেণি যে একই প্রসঙ্গে চলেছে সেই একই প্রসঙ্গে কীভাবে কাজ করতে পারে TransactionCommandHandlerDecorator? উদাহরণস্বরূপ, যদি সজ্জিত শ্রেণি InsertCommandHandlerশ্রেণি হয় তবে কীভাবে এটি প্রসঙ্গে সন্নিবেশ অপারেশনটি নিবন্ধিত করতে পারে (EF এ DbContext)?
মাসউদ

34

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

আমি http://mehdi.me/ambient-dbcontext-in-ef6/ উল্লেখ করব কারণ মেহেদি একটি দুর্দান্ত উত্স:

সম্ভাব্য পারফরম্যান্স লাভ।

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

এটি অলস-লোডিং সক্ষম করে।

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

মনে রাখবেন পাশাপাশি আছে কনস। এই লিঙ্কটিতে এই বিষয়টিতে পড়ার জন্য আরও অনেক সংস্থান রয়েছে।

অন্য কেউ যদি এই প্রশ্নটির উপর হোঁচট খায় এবং এই প্রশ্নের উত্তর যেহেতু প্রশ্নের সমাধান না করে তবে তা নিমগ্ন না হলে কেবল এটি পোস্ট করা।


ভাল লিঙ্ক! সুস্পষ্টভাবে DBContext পরিচালনা করা নিরাপদ পদ্ধতির মত দেখাচ্ছে।
অ্যাগসোল

34

মাইক্রোসফ্ট দ্বারা দুটি বিপরীত সুপারিশ রয়েছে এবং অনেকে DbContexts সম্পূর্ণরূপে বিচ্ছিন্নভাবে ব্যবহার করেন।

  1. একটি প্রস্তাবনা "DbContexts যত তাড়াতাড়ি সম্ভব তা নিষ্পত্তি করা" কারণ একটি DbContext অ্যালাইভ হ'ল ডিবি সংযোগ ইত্যাদির মতো মূল্যবান সংস্থান দখল করে ....
  2. অন্যটি বলে যে প্রতি অনুরোধের জন্য একটি ডিবি কনটেক্সট অত্যন্ত আদায়যোগ্য

যারা একে অপরের সাথে বিরোধিতা করে কারণ আপনার অনুরোধটি যদি ডিবি স্টাফের সাথে প্রচুর সম্পর্কহীন হয় তবে আপনার ডিবি কনটেক্সটটি অকারণে রাখা হয় is সুতরাং আপনার অনুরোধটি এলোমেলো জিনিস সম্পন্ন হওয়ার অপেক্ষায় থাকাকালীন আপনার DbContext কে বাঁচিয়ে রাখা অপব্যয় ...

বিধি 1 অনুসরণ করে এমন অনেক লোকের " ডিপোজিটরি প্যাটার্ন" এর ভিতরে তাদের DbContexts থাকে এবং ডেটাবেসেস কোয়েরি অনুসারে একটি নতুন ইনস্ট্যান্স তৈরি করে তাই এক্স অনুরোধ অনুসারে এক্স * ডিবি কনটেক্সট

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

কিপিং জীবিত একটি একক বহুমুখী DbContext দৃষ্টান্ত সুবিধাগুলো maximizes ক্যাশে কিন্তু যেহেতু DbContext হয় শংকা মুক্ত না এবং প্রতিটি ওয়েব অনুরোধ রান তে এটি নিজের থ্রেড আছে, প্রতি অনুরোধ একটি DbContext হয় দীর্ঘতম আপনি এটা রাখতে পারবেন না।

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

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

সুতরাং পরিশেষে এটি সক্রিয় যে একটি DbContext এর জীবনকাল এই দুটি পরামিতি মধ্যে সীমাবদ্ধ। ইউনিটঅফ ওয়ার্ক এবং থ্রেড


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

22

আমি বেশ নিশ্চিত যে এটি কারণ DbContext মোটেই থ্রেড নিরাপদ নয়। সুতরাং জিনিস ভাগ করে নেওয়া কখনই ভাল ধারণা নয়।


আপনি কি এইচটিটিপি অনুরোধ জুড়ে এটি ভাগ করে নেওয়া কখনও ভাল ধারণা হয় না?
অ্যান্ড্রু

2
হ্যাঁ অ্যান্ড্রু তার বোঝাতে চেয়েছিল। প্রসঙ্গটি ভাগ করা কেবলমাত্র একক থ্রেড ডেস্কটপ অ্যাপ্লিকেশানের জন্য।
এলিজাবেথ

10
একটি অনুরোধের জন্য প্রসঙ্গটি ভাগ করে নেওয়ার বিষয়ে কী। সুতরাং একটি অনুরোধের জন্য আমরা বিভিন্ন সংগ্রহস্থল অ্যাক্সেস করতে পারি এবং একটি এবং একই প্রসঙ্গে ভাগ করে তাদের জুড়ে লেনদেন করতে পারি?
লিউবুমির ভেলচেভ

16

প্রশ্ন বা আলোচনায় সত্যিকারভাবে সমাধান করা হয়নি এমন একটি বিষয় হ'ল DbContext পরিবর্তনগুলি বাতিল করতে পারে না। আপনি পরিবর্তনগুলি জমা দিতে পারেন, তবে আপনি পরিবর্তন গাছটি সাফ করতে পারবেন না, সুতরাং যদি আপনি কোনও অনুরোধের প্রসঙ্গ ব্যবহার করেন তবে আপনার যদি ভাগ্যের বাইরে থাকে তবে যে কোনও কারণেই যদি আপনাকে পরিবর্তনগুলি ফেলে দিতে হয় তবে।

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

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


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

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

সংক্ষেপে, আপনি যখন "প্রয়োজনে প্রসঙ্গটি পুনরায় তৈরি করার ক্ষমতা" বলছেন তখন আপনার অর্থ কী? আপনি কি নিজের রোলব্যাকের দক্ষতা রোল করছেন? আপনি একটি বাচ্চাদের বিস্তারিত বলতে পারেন?
tntwyckoff

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

আপনি কনটেইনারটিকে dbcontext এর আজীবন নিয়ন্ত্রণ করতে অনুমতি দেবেন কিনা এই প্রশ্নটি উত্থাপন করে যা কখনও কখনও অযৌক্তিকভাবে পিতামাতার নিয়ন্ত্রণগুলির আজীবন নিয়ন্ত্রণ করে। বলুন আমি যদি আমার কন্ট্রোলারগুলিতে একটি সাধারণ সার্ভিস সিঙ্গেলটন ইনজেকশন করতে চাই তবে প্রতি অনুরোধের কারণে আমি প্রতিযোগিতার কারণে কনডাক্টর ইনজেকশনটি ব্যবহার করতে পারব না।
ডেভিডকারার

10

আমি পূর্বের মতামতের সাথে একমত এটি বলা ভাল, আপনি যদি একক থ্রেড অ্যাপ্লিকেশনে DbContext ভাগ করতে যান তবে আপনার আরও স্মৃতি দরকার। উদাহরণস্বরূপ Azure- এ আমার ওয়েব অ্যাপ্লিকেশনটির (আরও একটি ছোট ছোট উদাহরণ) আরও 150 এমবি মেমরি দরকার এবং আমার প্রতি ঘন্টা 30 জন ব্যবহারকারী থাকে। HTTP রিকোয়েস্টে অ্যাপ্লিকেশন শেয়ারিং ডিবিসিঙ্কটেক্সট

এখানে আসল উদাহরণ চিত্র: 12PM এ প্রয়োগ করা হয়েছে


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

3

আমি এটি সম্পর্কে যা পছন্দ করি তা হ'ল এটি ওআরএম অর্থে কাজের ইউনিটটিকে (যেমন ব্যবহারকারী এটি দেখায় - যেমন একটি পৃষ্ঠা জমা দেয়) সারিবদ্ধ করে।

অতএব, আপনি সম্পূর্ণ পৃষ্ঠা জমা দেওয়ার লেনদেন করতে পারেন, যা আপনি প্রতিটি নতুন প্রসঙ্গ তৈরির সাথে সিআরইউডি পদ্ধতিগুলি প্রকাশ করে দিলে আপনি করতে পারেন নি।


2

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

যে সমস্যাটি হ'ল একটি সিঙ্গলটন DbContext এমন একটি টাইম বোমা হয়ে উঠতে পারে যা শেষ পর্যন্ত পুরো ডাটাবেসটিকে + মেমরিতে নেট নেট অবজেক্টের ওভারহেডকে ক্যাশে করতে পারে।

.NoTracking()এক্সটেনশন পদ্ধতির সাথে লিনক অনুসন্ধানগুলি ব্যবহার করে এই আচরণের বিভিন্ন উপায় রয়েছে । এছাড়াও আজকাল পিসিগুলিতে প্রচুর র‍্যাম রয়েছে। তবে সাধারণত এটি পছন্দসই আচরণ নয়।


এটি সঠিক, তবে আপনাকে ধরে নিতে হবে যে আবর্জনা সংগ্রাহক কাজ করবে, এই সমস্যাটিকে বাস্তবের চেয়ে আরও ভার্চুয়াল করে তুলবে।
টোক্কোভিল

2
আবর্জনা সংগ্রাহক কোনও সক্রিয় স্ট্যাটিক / সিঙ্গলটন অবজেক্টের দ্বারা রাখা কোনও বস্তুর উদাহরণ সংগ্রহ করতে যাচ্ছেন না। তারা স্তূপের জেনার 2 এ শেষ হবে।
দিমিত্রি এস

1

সত্তা ফ্রেমওয়ার্কের সাথে সন্ধান করার জন্য আরেকটি বিষয় হ'ল বিশেষভাবে নতুন সত্তা তৈরির, অলস লোডিংয়ের মিশ্রণটি ব্যবহার করার পরে এবং সেই নতুন সত্তা (একই প্রসঙ্গে) ব্যবহার করার সময়। আপনি IDbSet.Create (বনাম সবেমাত্র নতুন) ব্যবহার না করলে, সেই সত্তার উপর অলস লোডিং কাজ করা হয় না যখন এটি তৈরি করা প্রসঙ্গে থেকে পুনরুদ্ধার করা হয়েছিল Example উদাহরণ:

 public class Foo {
     public string Id {get; set; }
     public string BarId {get; set; }
     // lazy loaded relationship to bar
     public virtual Bar Bar { get; set;}
 }
 var foo = new Foo {
     Id = "foo id"
     BarId = "some existing bar id"
 };
 dbContext.Set<Foo>().Add(foo);
 dbContext.SaveChanges();

 // some other code, using the same context
 var foo = dbContext.Set<Foo>().Find("foo id");
 var barProp = foo.Bar.SomeBarProp; // fails with null reference even though we have BarId set.
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.