मेरे पास भंडार है जैसे

public interface IEmployeeRepository
{
  Task<EmployeeSettings> GetEmployeeSettings(int employeeId);
  Task<ICollection<DepartmentWorkPosition>> GetWorkPositions(int employeeId);
}

रिपॉजिटरी का कंस्ट्रक्टर (DbContext इंजेक्शन):

public EmployeeRepository(EmployeeDbContext dbContext)
{
  _dbContext = dbContext;
}

और इसे EF Core 2.0 में कॉल करें जैसे

var settingsTask = _employeeRepository
    .GetEmployeeSettings(employeeId.Value);

var workPositionsTask = _employeeRepository
    .GetWorkPositions(employeeId.Value);

await Task.WhenAll(settingsTask, workPositionsTask);

// do other things...

संकट:

ईएफ कोर 3.0 के साथ अमान्यऑपरेशन अपवाद है: पिछले ऑपरेशन पूरा होने से पहले इस संदर्भ में एक दूसरा ऑपरेशन शुरू हुआ ...

DbContext ConfigureServices जैसे . में पंजीकृत है

services.AddDbContext<EmployeeDbContext>(ServiceLifetime.Transient);

ट्यूटोरियल निम्नलिखित कहता है: एंटिटी फ्रेमवर्क कोर एक ही डीबीकॉन्टेक्स्ट इंस्टेंस पर चल रहे एकाधिक समांतर संचालन का समर्थन नहीं करता है।

परंतु! एसिंक में भंडारों के साथ इसका उपयोग कैसे करें?

5
Arsync 26 सितंबर 2019, 20:51

3 जवाब

सबसे बढ़िया उत्तर

एसिंक में भंडारों के साथ इसका उपयोग कैसे करें?

आपके पास प्रति रिपोजिटरी में केवल एक साथ-साथ अतुल्यकालिक अनुरोध हो सकता है। यदि आपको एक समय में एक से अधिक रखने की आवश्यकता है, तो आपको एक से अधिक भंडार की आवश्यकता है। इसके लिए आपको अपने प्रकारों में एक रिपॉजिटरी कारखाना इंजेक्ट करने की आवश्यकता हो सकती है।

2
Stephen Cleary 27 सितंबर 2019, 00:39
लेकिन क्यों? सर्वर से डेटा की प्रतीक्षा करने वाले दो समानांतर प्रश्नों में क्या गलत है? विभिन्न संदर्भों का उपयोग प्रदर्शन हिट का तात्पर्य है, क्योंकि संदर्भ बनाए जाने पर कुछ सामान प्रारंभ करते हैं - मुझे लगता है कि पूलिंग इसे हल करेगी।
 – 
Miha Markic
30 सितंबर 2019, 17:52
@ मिहामार्किक: मैं गलत हो सकता था, लेकिन मेरा मानना ​​​​है कि इसका कारण यह है कि एक एकल डीबी कनेक्शन का उपयोग केवल एक समय में एक परिणाम सेट को स्ट्रीम करने के लिए किया जा सकता है। दूसरे को स्ट्रीम करने के लिए, दूसरे कनेक्शन की आवश्यकता होगी। प्रति कनेक्शन एकाधिक एक साथ परिणाम सेट करने का एक तरीका है लेकिन मुझे नहीं लगता कि ईएफ इसका समर्थन करता है।
 – 
Stephen Cleary
30 सितंबर 2019, 18:07
मैं भी यही सोचूंगा। हालांकि, पुराना अच्छा ado.net अभ्यास एक कनेक्शन खोलना है, जो आपको करना है उसे करें और तुरंत बाद इसका निपटान करें - इसलिए यह पूल में वापस चला जाता है। मुझे आश्चर्य है कि किस निर्णय ने ईएफ टीम को एक ही कनेक्शन के साथ जाने के लिए प्रेरित किया (अनुमान लगाया)।
 – 
Miha Markic
30 सितंबर 2019, 20:55
ईएफ प्रदाता निर्धारित करता है कि कनेक्शन कैसे प्रबंधित किए जाते हैं, और मेरा मानना ​​​​है कि सभी बड़े नाम प्रदाता कनेक्शन पूलिंग का उपयोग करते हैं।
 – 
Stephen Cleary
30 सितंबर 2019, 23:04
एकाधिक सक्रिय परिणाम सेट को एक समय में एक से अधिक परिणामों को संभालना चाहिए, मेरा अनुमान है कि प्रत्येक परिणाम का क्लाइंट साइड भौतिककरण एक समय निष्पादन में एक के लिए बहुप्रचारित या कतारबद्ध नहीं किया जा सकता है .... जो शर्म की बात है क्योंकि यह 2.2 में काम करता है। और एक साथ कई संभावित लंबे समय तक चलने वाले प्रश्नों को एक साथ शुरू करना बहुत आसान बना दिया।
 – 
Bob Provencher
31 अक्टूबर 2019, 05:15

फ़ैक्टरी और एक्सप्लोरेशन इंस्टेंट संदर्भ का उपयोग करें।

Startup.cs

//classical dbcontext registration
services.AddDbContext<TestDB>(
            options => options.UseSqlServer(
                Configuration.GetConnectionString("Test")));

//factory
//in case we want parallellize more queries at the same request, we can't use the same connection. So, because dbcontext is instantiate at request time this would  generate exception, so we need to use factory and explicit "using" to explicitly manage dbcontext lifetime
var optionsBuilder = new DbContextOptionsBuilder<TestDB>();
        optionsBuilder.UseSqlServer(Configuration.GetConnectionString("Test"));
        services.AddSingleton(s => new Func<TestDB>(() => new TestDB(optionsBuilder.Options)));

सेवा वर्ग

public class TestService
{
    private readonly TestDB _testDb;
    private readonly Func<TestDB> _testDbfunct;

    public TestService(TestDB testDb, Func<TestDB> testDbfunct)
    {
        _testDb = testDb;
        _testDbfunct = testDbfunct;
    }

    //mixed classical request dbcontext and factory approaches
    public async Task<string> TestMultiple(int id, bool newConnection = false) //we need to add optional newConnection parameter and the end of other parameters
    {
        //use request connection (_testDb) if newconnection is false, otherwise instantiate a new connection using factory. null inside "using" means that "using" is not used
        //use newconnection = true if you want run parallel queries, so you need different connection for each one
        TestDB testDb = _testDb;
        using (newConnection ? testDb = _testDbfunct() : null)
        {
            return await (from t in testDb.Table where t.id == id select t.code).FirstOrDefaultAsync();

        }
    }
}

टेस्ट क्लास

    //instantiate dbcontext for each call, so we can parallellize
    [TestMethod]
    public async Task TestMultiple()
    { 
        //test1 and test2 starts in parallel without test2 that need to wait the end of test1. For each one a Task in returned
        var test1 = _testService.TestMultiple(1,true);
        var test2 = _testService.TestMultiple(2,true);

        //wait test1 and test2 return
        string code1 = await test1;
        string code2 = await test2;

    }
    
    //use request dbcontext
    [TestMethod]
    public async Task TestClassic()
    {
        string code = await _testService.TestMultiple(3);

    }

एनबी: नए .नेट कोर 5 में आप मेरे उदाहरण में कस्टम फैक्ट्री बनाने के बजाय बिल्डिन AddDbContextFactory का उपयोग कर सकते हैं

0
Alessandro Lazzara 22 नवम्बर 2020, 12:28
यहां कोई समानांतर कोड नहीं है। आप दोनों परीक्षण विधियों की प्रतीक्षा कर रहे हैं।
 – 
Gert Arnold
22 नवम्बर 2020, 00:04
नमस्ते। मैं इंतजार करता हूं जब वे दोनों शुरू होते हैं (दूसरा शुरू करने के लिए पहले खत्म होने की प्रतीक्षा न करें)। योन यह भी लिख सकता है: कार्य का इंतजार करें। जब सभी (टेस्ट 1, टेस्ट 2) और आपके पास अपवाद नहीं है क्योंकि 2 अलग-अलग संदर्भों का उपयोग किया जाता है;
 – 
Alessandro Lazzara
22 नवम्बर 2020, 00:22
मैं एक .Net 5.0 DBContextFactory समाधान देखना पसंद करूंगा। क्या आप नए कोड के उदाहरण में जोड़ सकते हैं?
 – 
Pangamma
6 मार्च 2021, 02:01

बस लिखें:

var settings = await _employeeRepository.GetEmployeeSettings(employeeId.Value);
var workPositions = await _employeeRepository.GetWorkPositions(employeeId.Value);

हाँ। ईएफ कोर एक ही संदर्भ उदाहरण पर चलाए जा रहे कई समानांतर संचालन का समर्थन नहीं करता है। अगला ऑपरेशन शुरू करने से पहले आपको हमेशा किसी ऑपरेशन के पूरा होने की प्रतीक्षा करनी चाहिए। यह आमतौर पर प्रत्येक async ऑपरेशन पर प्रतीक्षित कीवर्ड का उपयोग करके किया जाता है। देखें https://docs.microsoft.com/en-us/ एफई/कोर/क्वेरी/एसिंक

-2
Andrei Kostyrin 31 अक्टूबर 2019, 12:52
1
डाउनवॉटेड: सवाल यह नहीं है कि इन दो प्रश्नों को कैसे चलाया जाए, बल्कि उन्हें समानांतर में कैसे चलाया जाए?
 – 
dyesdyes
30 मार्च 2020, 17:41
समानांतर के रूप में उपयोग करने के कोई तरीके नहीं हैं। कृपया मेरी टिप्पणी पढ़ें।
 – 
Andrei Kostyrin
2 अप्रैल 2020, 22:54