Entity Framework มี DataReader แบบเปิดที่เชื่อมโยงกับคำสั่งนี้อยู่แล้ว


285

ฉันใช้ Entity Framework และบางครั้งฉันจะได้รับข้อผิดพลาดนี้

EntityCommandExecutionException
{"There is already an open DataReader associated with this Command which must be closed first."}
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands...

แม้ว่าฉันจะไม่ได้ทำการจัดการการเชื่อมต่อด้วยตนเอง

ข้อผิดพลาดนี้เกิดขึ้นเป็นระยะ

รหัสที่ก่อให้เกิดข้อผิดพลาด (สั้นลงเพื่อความสะดวกในการอ่าน):

        if (critera.FromDate > x) {
            t= _tEntitites.T.Where(predicate).ToList();
        }
        else {
            t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
        }

ใช้รูปแบบการกำจัดเพื่อเปิดการเชื่อมต่อใหม่ทุกครั้ง

using (_tEntitites = new TEntities(GetEntityConnection())) {

    if (critera.FromDate > x) {
        t= _tEntitites.T.Where(predicate).ToList();
    }
    else {
        t= new List<T>(_tEntitites.TA.Where(historicPredicate).ToList());
    }

}

ยังคงเป็นปัญหาอยู่

เหตุใด EF จึงไม่นำการเชื่อมต่อกลับมาใช้ใหม่หากเปิดอยู่แล้ว


1
ฉันรู้ว่าคำถามนี้โบราณ แต่ฉันสนใจที่จะรู้ว่าคุณpredicateและhistoricPredicateตัวแปรประเภทใด ฉันได้ค้นพบว่าถ้าคุณผ่านFunc<T, bool>ไปWhere()มันจะรวบรวมและบางครั้งการทำงาน (เพราะมันไม่ "ที่" ในความทรงจำ) สิ่งที่คุณควรจะทำคือผ่านไปExpression<Func<T, bool>> Where()
James

คำตอบ:


351

มันไม่เกี่ยวกับการปิดการเชื่อมต่อ EF จัดการการเชื่อมต่ออย่างถูกต้อง ความเข้าใจของฉันเกี่ยวกับปัญหานี้คือมีคำสั่งการดึงข้อมูลหลายคำสั่งที่ดำเนินการในการเชื่อมต่อเดียว (หรือคำสั่งเดียวที่มีการเลือกหลายรายการ) ในขณะที่ DataReader ถัดไปจะดำเนินการก่อนที่คำสั่งแรกจะเสร็จสิ้นการอ่าน วิธีเดียวที่จะหลีกเลี่ยงข้อยกเว้นคืออนุญาตให้ DataReaders หลายระดับซ้อนกัน = เปิด MultipleActiveResultSets สถานการณ์อื่นที่เกิดขึ้นเสมอคือเมื่อคุณวนซ้ำตามผลลัพธ์ของแบบสอบถาม (IQueryable) และคุณจะทริกเกอร์การโหลดที่ขี้เกียจสำหรับเอนทิตีที่โหลดภายในการทำซ้ำ


2
ที่จะทำให้รู้สึก แต่มีเพียงหนึ่งตัวเลือกในแต่ละวิธี
Sonic Soul

1
@Sonic: นั่นคือคำถาม อาจมีมากกว่าหนึ่งคำสั่งดำเนินการ แต่คุณไม่เห็นมัน ฉันไม่แน่ใจว่าสามารถติดตามสิ่งนี้ใน Profiler ได้หรือไม่ (ยกเว้นสามารถโยนทิ้งได้ก่อนที่ผู้อ่านที่สองจะถูกเรียกใช้) คุณยังสามารถลองส่งแบบสอบถามไปยัง ObjectQuery และโทร ToTraceString เพื่อดูคำสั่ง SQL มันยากที่จะติดตาม ฉันเปิดใช้ MARS เสมอ
Ladislav Mrnka

2
@Sonic: ไม่มีความตั้งใจของฉันคือการตรวจสอบการดำเนินการและคำสั่ง SQL ที่เสร็จสมบูรณ์
Ladislav Mrnka

11
ยอดเยี่ยมปัญหาของฉันคือสถานการณ์ที่สอง: 'เมื่อคุณทำซ้ำผ่านผลลัพธ์ของแบบสอบถาม (IQueryable) และคุณจะเรียกใช้การโหลดที่ขี้เกียจสำหรับเอนทิตีที่โหลดภายในการทำซ้ำ'
Amr Elgarhy

6
การเปิดใช้งาน MARS อาจมีผลข้างเคียงที่ไม่ดี: designlimbo.com/?p=235
Søren Boisen

126

อีกวิธีหนึ่งคือการใช้ MARS (MultipleActiveResultSets) คุณสามารถเขียนโค้ดเพื่อไม่ให้เปิดชุดผลลัพธ์หลายชุด

สิ่งที่คุณสามารถทำได้คือการดึงข้อมูลไปยังหน่วยความจำในแบบที่คุณจะไม่เปิดอ่าน มักจะเกิดจากการวนซ้ำชุดผลลัพธ์ในขณะที่พยายามเปิดชุดผลลัพธ์อื่น

รหัสตัวอย่าง:

public class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

public class Blog
{
    public int BlogID { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int PostID { get; set; }
    public virtual Blog Blog { get; set; }
    public string Text { get; set; }
}

ให้บอกว่าคุณกำลังค้นหาในฐานข้อมูลของคุณที่มีสิ่งเหล่านี้:

var context = new MyContext();

//here we have one resultset
var largeBlogs = context.Blogs.Where(b => b.Posts.Count > 5); 

foreach (var blog in largeBlogs) //we use the result set here
{
     //here we try to get another result set while we are still reading the above set.
    var postsWithImportantText = blog.Posts.Where(p=>p.Text.Contains("Important Text"));
}

เราสามารถแก้ไขปัญหานี้ได้ง่ายๆโดยเพิ่ม. ToList ()ดังนี้:

var largeBlogs = context.Blogs.Where(b => b.Posts.Count > 5).ToList();

สิ่งนี้บังคับให้เอนทิตีเฟรมเวิร์กโหลดรายการลงในหน่วยความจำดังนั้นเมื่อเราวนซ้ำในลูป foreach จะไม่ใช้ตัวอ่านข้อมูลเพื่อเปิดรายการอีกต่อไป แต่จะอยู่ในหน่วยความจำแทน

ฉันรู้ว่านี่อาจไม่เป็นที่ต้องการหากคุณต้องการที่จะโหลดคุณสมบัติบางอย่าง นี่คือตัวอย่างส่วนใหญ่ที่หวังว่าจะอธิบายวิธี / สาเหตุที่คุณอาจได้รับปัญหานี้เพื่อให้คุณสามารถตัดสินใจได้อย่างถูกต้อง


7
วิธีนี้ใช้ได้ผลสำหรับฉัน เพิ่ม. ToList () ทันทีหลังจากการสอบถามและก่อนทำสิ่งอื่นใดกับผลลัพธ์
TJKjaer

9
ระวังด้วยสิ่งนี้และใช้สามัญสำนึก หากคุณกำลังToListพันวัตถุมันจะเพิ่มหน่วยความจำตัน ในตัวอย่างที่เฉพาะเจาะจงนี้คุณจะดีกว่าที่จะรวมการสืบค้นภายในกับแบบสอบถามแรกเพื่อให้มีการสร้างแบบสอบถามเพียงหนึ่งแบบสอบถามแทนที่จะเป็นสองแบบสอบถาม
kamranicus

4
@subkamran ประเด็นของฉันคือว่าคิดเกี่ยวกับบางสิ่งบางอย่างและเลือกสิ่งที่เหมาะสมกับสถานการณ์ไม่ใช่แค่ทำ ตัวอย่างที่เป็นเพียงสิ่งที่ฉันสุ่มคิดขึ้นเพื่ออธิบาย :)
จิมวูล์ฟ

3
แน่นอนฉันแค่อยากจะชี้ให้มันออกมาอย่างชัดเจนสำหรับคัดลอก / วางความสุขคน :)
kamranicus

อย่ายิงฉัน แต่นี่ไม่ได้เป็นทางออกสำหรับคำถาม ตั้งแต่เมื่อ "ดึงข้อมูลในหน่วยความจำ" ทางออกสำหรับปัญหาที่เกี่ยวข้องกับ SQL? ฉันชอบเป็นช่างพูดกับฐานข้อมูลดังนั้นฉันไม่ต้องการดึงบางสิ่งบางอย่างในหน่วยความจำ "เพราะมิฉะนั้นจะมีข้อยกเว้น SQL ถูกโยน" อย่างไรก็ตามในรหัสของคุณที่ให้ไว้ไม่มีเหตุผลที่จะติดต่อฐานข้อมูลสองครั้ง ง่ายในการโทรเพียงครั้งเดียว ระมัดระวังข้อความเช่นนี้ ToList, First, Single, ... ควรใช้เมื่อจำเป็นต้องใช้ข้อมูลในหน่วยความจำเท่านั้น (ดังนั้นต้องเป็นข้อมูลที่คุณต้องการเท่านั้น) ไม่ใช่เมื่อข้อยกเว้น SQL กำลังเกิดขึ้นเป็นอย่างอื่น
Frederik Prijck

70

มีวิธีอื่นในการเอาชนะปัญหานี้ ไม่ว่าจะเป็นวิธีที่ดีกว่านั้นขึ้นอยู่กับสถานการณ์ของคุณ

ปัญหาเกิดจากการโหลดแบบ lazy ดังนั้นวิธีหนึ่งในการหลีกเลี่ยงการโหลดแบบ lazy นั้นผ่านการใช้การรวม:

var results = myContext.Customers
    .Include(x => x.Orders)
    .Include(x => x.Addresses)
    .Include(x => x.PaymentMethods);

หากคุณใช้Includes ที่เหมาะสมคุณสามารถหลีกเลี่ยงการเปิดใช้งาน MARS แต่ถ้าคุณพลาดคุณจะได้รับข้อผิดพลาดดังนั้นการเปิดใช้งาน MARS อาจเป็นวิธีที่ง่ายที่สุดในการแก้ไข


1
ทำงานเหมือนจับใจ .Includeเป็นทางออกที่ดีกว่าการเปิดใช้งาน MARS และง่ายกว่าการเขียนรหัสแบบสอบถาม SQL ของคุณเอง
Nolonar

15
หากใครก็ตามมีปัญหาที่คุณสามารถเขียนได้เฉพาะ. "(รวมถึง" สตริง ") ไม่ใช่แลมบ์ดาคุณต้องเพิ่ม" using System.Data.Entity "เพราะวิธีการขยายตั้งอยู่ที่นั่น
Jim Wolff

46

คุณได้รับข้อผิดพลาดนี้เมื่อคอลเลกชันที่คุณพยายามทำซ้ำเป็นการโหลดแบบสันหลังยาว (IQueriable)

foreach (var user in _dbContext.Users)
{    
}

การแปลงชุด IQueriable เป็นชุดสะสมอื่น ๆ จะช่วยแก้ปัญหานี้ได้ ตัวอย่าง

_dbContext.Users.ToList()

หมายเหตุ: .ToList () สร้างชุดใหม่ทุกครั้งและอาจทำให้เกิดปัญหาประสิทธิภาพหากคุณกำลังจัดการกับข้อมูลขนาดใหญ่


1
ทางออกที่ง่ายที่สุด! Big UP;)
Jacob Sobus

1
การดึงรายการที่ไม่มีขอบเขตอาจทำให้เกิดปัญหาประสิทธิภาพที่รุนแรง! ทุกคนสามารถโหวตได้อย่างไร
SandRock

1
@SandRock ไม่ได้สำหรับคนที่ทำงานให้กับ บริษัท ขนาดเล็ก - SELECT COUNT(*) FROM Users= 5
Simon_Weaver

5
ลองคิดดูสองครั้ง นักพัฒนาหนุ่มที่อ่านคำถามนี้อาจคิดว่านี่เป็นทางออกตลอดเวลาเมื่อไม่แน่นอน ฉันขอแนะนำให้คุณแก้ไขคำตอบของคุณเพื่อเตือนผู้อ่านเกี่ยวกับอันตรายของการดึงรายการที่ไม่มีขอบเขตจากฐานข้อมูล
SandRock

1
@SandRock ฉันคิดว่านี่จะเป็นสถานที่ที่ดีสำหรับคุณในการเชื่อมโยงคำตอบหรือบทความที่อธิบายวิธีปฏิบัติที่ดีที่สุด
สินใจ

13

ฉันแก้ไขปัญหาได้อย่างง่ายดาย (ในทางปฏิบัติ) โดยการเพิ่มตัวเลือกให้กับตัวสร้าง ดังนั้นฉันจะใช้เมื่อจำเป็นเท่านั้น

public class Something : DbContext
{
    public Something(bool MultipleActiveResultSets = false)
    {
        this.Database
            .Connection
            .ConnectionString = Shared.ConnectionString /* your connection string */
                              + (MultipleActiveResultSets ? ";MultipleActiveResultSets=true;" : "");
    }
...

2
ขอบคุณ. มันใช้งานได้ดี ฉันเพิ่งเพิ่ม MultipleActiveResultSets = true ในสตริงการเชื่อมต่อโดยตรงใน web.config
Mosharaf Hossain

11

MultipleActiveResultSets=trueลองในสตริงการเชื่อมต่อกับชุด สิ่งนี้ทำให้การทำงานหลายอย่างในฐานข้อมูล

Server=yourserver ;AttachDbFilename=database;User Id=sa;Password=blah ;MultipleActiveResultSets=true;App=EntityFramework

ที่เหมาะกับฉัน ... ไม่ว่าการเชื่อมต่อของคุณใน app.config หรือคุณตั้งไว้โดยทางโปรแกรม ... หวังว่าสิ่งนี้จะเป็นประโยชน์


MultipleActiveResultSets = true ที่เพิ่มลงในสตริงการเชื่อมต่อของคุณอาจจะแก้ปัญหาได้ สิ่งนี้ไม่ควรลงคะแนน
Aaron Hudon

ใช่แน่ใจว่าฉันได้สาธิตวิธีเพิ่มลงในสตริงการเชื่อมต่อของคุณแล้ว
Mohamed Hocine

4

เดิมทีฉันตัดสินใจใช้ฟิลด์คงที่ในคลาส API ของฉันเพื่ออ้างอิงอินสแตนซ์ของวัตถุ MyDataContext (โดยที่ MyDataContext เป็นวัตถุบริบท EF5) แต่นั่นคือสิ่งที่ดูเหมือนว่าจะสร้างปัญหา ฉันเพิ่มรหัสบางอย่างเช่นต่อไปนี้ให้กับทุกวิธี API ของฉันและแก้ไขปัญหาได้

using(MyDBContext db = new MyDBContext())
{
    //Do some linq queries
}

ตามที่คนอื่น ๆ ระบุไว้วัตถุบริบทข้อมูลของ EF ไม่ปลอดภัยสำหรับเธรด ดังนั้นการวางไว้ในวัตถุคงที่ในที่สุดจะทำให้เกิดข้อผิดพลาด "data reader" ภายใต้เงื่อนไขที่เหมาะสม

ข้อสันนิษฐานเดิมของฉันคือการสร้างวัตถุเพียงอินสแตนซ์เดียวจะมีประสิทธิภาพมากขึ้นและสามารถจัดการหน่วยความจำได้ดีขึ้น จากสิ่งที่ฉันได้รวบรวมการค้นคว้าปัญหานี้ไม่ใช่กรณี ในความเป็นจริงดูเหมือนว่าจะมีประสิทธิภาพมากกว่าในการจัดการการโทรแต่ละครั้งไปยัง API ของคุณว่าเป็นเหตุการณ์ที่ปลอดภัยและแยกเธรด ตรวจสอบให้แน่ใจว่าทรัพยากรทั้งหมดได้รับการปล่อยตัวอย่างถูกต้องเมื่อวัตถุออกนอกขอบเขต

โดยเฉพาะอย่างยิ่งถ้าคุณนำ API ของคุณไปสู่ความก้าวหน้าตามธรรมชาติครั้งต่อไปซึ่งจะเป็นการเปิดเผยว่าเป็น WebService หรือ REST API

การเปิดเผย

  • ระบบปฏิบัติการ: Windows Server 2012
  • .NET: ติดตั้ง 4.5, โครงการโดยใช้ 4.0
  • แหล่งข้อมูล: MySQL
  • Application Framework: MVC3
  • การรับรองความถูกต้อง: แบบฟอร์ม

3

ฉันสังเกตเห็นว่าข้อผิดพลาดนี้เกิดขึ้นเมื่อฉันส่ง IQueriable ไปยังมุมมองและใช้ในการ foreach สองครั้งที่ foreach ภายในยังต้องใช้การเชื่อมต่อ ตัวอย่างง่ายๆ (ViewBag.parents สามารถเป็น IQueriable หรือ DbSet):

foreach (var parent in ViewBag.parents)
{
    foreach (var child in parent.childs)
    {

    }
}

ทางออกที่ง่ายคือการใช้.ToList()กับคอลเลกชันก่อนที่จะใช้ โปรดทราบว่า MARS ไม่สามารถใช้งานกับ MySQL ได้


ขอบคุณ! ทุกอย่างที่นี่กล่าวว่า "ลูปซ้อนกันเป็นปัญหา" แต่ไม่มีใครพูดถึงวิธีการแก้ไข ฉันใช้ToList()สายแรกเพื่อรับชุดจากฐานข้อมูล จากนั้นฉันก็ทำforeachรายการนั้นและการโทรที่ตามมาทำงานได้อย่างสมบูรณ์แทนที่จะให้ข้อผิดพลาด
AlbatrossCafe

@AlbatrossCafe ... แต่ไม่มีใครพูดถึงว่าในกรณีนี้ข้อมูลของคุณจะถูกโหลดไปยังหน่วยความจำและการสืบค้นจะถูกดำเนินการในหน่วยความจำแทน DB
Lightning3

3

ฉันพบว่าฉันมีข้อผิดพลาดเหมือนกันและมันเกิดขึ้นเมื่อฉันใช้Func<TEntity, bool>แทนของExpression<Func<TEntity, bool>>คุณpredicateสำหรับคุณ

เมื่อฉันเปลี่ยนทั้งหมดFunc'sเป็นExpression'sยกเว้นหยุดถูกโยน

ฉันเชื่อว่าEntityFramworkจะทำสิ่งที่ฉลาดบางอย่างExpression'sที่มันไม่ได้ทำFunc's


สิ่งนี้ต้องการ upvotes มากขึ้น ฉันพยายามสร้างวิธีในคลาส DataContext ของฉัน(MyTParent model, Func<MyTChildren, bool> func)เพื่อให้ ViewModels ของฉันสามารถระบุส่วนที่แน่นอนwhereให้กับวิธี Generic DataContext ไม่มีอะไรทำงานจนกว่าฉันจะทำสิ่งนี้
Justin

3

2 วิธีแก้ไขเพื่อลดปัญหานี้:

  1. บังคับให้หน่วยความจำแคชทำการโหลดอย่างสันหลังยาว.ToList()หลังจากที่คิวรีของคุณดังนั้นคุณจึงสามารถวนซ้ำผ่านการเปิด DataReader ใหม่ได้
  2. .Include(/ เอนทิตีเพิ่มเติมที่คุณต้องการโหลดในแบบสอบถาม /) นี้เรียกว่าการโหลดกระตือรือร้นซึ่งช่วยให้คุณ (แน่นอน) รวมวัตถุที่เกี่ยวข้อง (เอนทิตี) ในระหว่างที่เขาดำเนินการของแบบสอบถามด้วย DataReader

2

พื้นกลางที่ดีระหว่างการเปิดใช้งาน MARS และการดึงผลลัพธ์ทั้งหมดที่ตั้งไว้ในหน่วยความจำคือการดึง ID เฉพาะในการสืบค้นเริ่มต้นจากนั้นวนรอบ ID ที่ทำให้แต่ละเอนทิตีเป็นจริง

ตัวอย่างเช่น (ใช้เอนทิตีตัวอย่าง "บล็อกและโพสต์" ดังในคำตอบนี้ ):

using (var context = new BlogContext())
{
    // Get the IDs of all the items to loop through. This is
    // materialized so that the data reader is closed by the
    // time we're looping through the list.
    var blogIds = context.Blogs.Select(blog => blog.Id).ToList();

    // This query represents all our items in their full glory,
    // but, items are only materialized one at a time as we
    // loop through them.
    var blogs =
        blogIds.Select(id => context.Blogs.First(blog => blog.Id == id));

    foreach (var blog in blogs)
    {
        this.DoSomethingWith(blog.Posts);

        context.SaveChanges();
    }
}

การทำเช่นนี้หมายความว่าคุณดึงจำนวนเต็มสองสามพันเข้าไปในหน่วยความจำเท่านั้นซึ่งตรงข้ามกับกราฟวัตถุทั้งหมดนับพันซึ่งควรลดการใช้หน่วยความจำในขณะที่ช่วยให้คุณทำงานแต่ละรายการโดยไม่เปิดใช้งาน MARS

ประโยชน์ที่ดีอีกประการหนึ่งของสิ่งนี้ตามที่เห็นในตัวอย่างคือคุณสามารถบันทึกการเปลี่ยนแปลงในขณะที่คุณวนซ้ำในแต่ละรายการแทนที่จะต้องรอจนถึงจุดสิ้นสุดของลูป (หรือวิธีแก้ปัญหาอื่น ๆ ) ตามที่ต้องการแม้กับ เปิดใช้งาน MARS (ดูที่นี่และที่นี่ )


context.SaveChanges();ภายในลูป :( นี่ไม่ดีมันต้องอยู่นอกลูป
Jawand Singh

1

ในกรณีของฉันฉันพบว่ามีคำสั่ง "await" ที่หายไปก่อนการโทร myContext.SaveChangesAsync () การเพิ่มการรอก่อนที่การโทรแบบอะซิงก์จะแก้ไขปัญหาตัวอ่านข้อมูลให้ฉัน


0

หากเราพยายามจัดกลุ่มเงื่อนไขของเราเป็นวิธี Func <> หรือส่วนขยายเราจะได้รับข้อผิดพลาดนี้สมมติว่าเรามีรหัสดังนี้:

public static Func<PriceList, bool> IsCurrent()
{
  return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
              (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

Or

public static IEnumerable<PriceList> IsCurrent(this IEnumerable<PriceList> prices) { .... }

สิ่งนี้จะทำให้เกิดข้อยกเว้นถ้าเราพยายามใช้ในที่ไหน () สิ่งที่เราควรทำแทนคือการสร้างเพรดิเคตแบบนี้:

public static Expression<Func<PriceList, bool>> IsCurrent()
{
    return p => (p.ValidFrom == null || p.ValidFrom <= DateTime.Now) &&
                (p.ValidTo == null || p.ValidTo >= DateTime.Now);
}

ข้อมูลเพิ่มเติมสามารถอ่านได้ที่: http://www.albahari.com/nutshell/predicatebuilder.aspx


0

ปัญหานี้สามารถแก้ไขได้ง่ายๆโดยการแปลงข้อมูลเป็นรายการ

 var details = _webcontext.products.ToList();


            if (details != null)
            {
                Parallel.ForEach(details, x =>
                {
                    Products obj = new Products();
                    obj.slno = x.slno;
                    obj.ProductName = x.ProductName;
                    obj.Price = Convert.ToInt32(x.Price);
                    li.Add(obj);

                });
                return li;
            }

ToList () ทำการโทร แต่รหัสด้านบนยังไม่ได้ยกเลิกการเชื่อมต่อ ดังนั้น _webcontext ของคุณยังคงมีความเสี่ยงที่จะถูกปิดในช่วงเวลาที่ 1
Sonic Soul

0

ในสถานการณ์ของฉันปัญหาเกิดขึ้นเนื่องจากการลงทะเบียนการฉีดพึ่งพา ฉันกำลังฉีดบริการขอบเขตการร้องขอต่อที่ใช้ dbcontext เป็นบริการลงทะเบียนเดี่ยว ดังนั้น dbcontext นั้นถูกใช้ภายในการร้องขอหลายครั้งดังนั้นจึงเกิดข้อผิดพลาด


0

ในกรณีของฉันปัญหาไม่มีอะไรเกี่ยวข้องกับสตริงการเชื่อมต่อ MARS แต่ด้วยการทำให้เป็นอนุกรม json หลังจากอัปเกรดโครงการของฉันจาก NetCore2 เป็น 3 ฉันได้รับข้อผิดพลาดนี้

ข้อมูลเพิ่มเติมสามารถดูได้ที่นี่


-6

ฉันแก้ไขปัญหานี้โดยใช้ส่วนของรหัสต่อไปนี้ก่อนการสืบค้นครั้งที่สอง:

 ...first query
 while (_dbContext.Connection.State != System.Data.ConnectionState.Closed)
 {
     System.Threading.Thread.Sleep(500);
 }
 ...second query

คุณสามารถเปลี่ยนเวลานอนในหน่วยมิลลิวินาที

PD มีประโยชน์เมื่อใช้เธรด


13
การเพิ่ม Thread.Sleep โดยพลการในการแก้ปัญหาใด ๆ เป็นการปฏิบัติที่ไม่ดี - และโดยเฉพาะอย่างยิ่งเมื่อใช้ในการก้าวเท้าเลี่ยงปัญหาที่แตกต่างกันซึ่งสถานะของค่าบางอย่างไม่เป็นที่เข้าใจอย่างสมบูรณ์ ฉันคิดว่า "การใช้เธรด" ตามที่ระบุไว้ที่ด้านล่างของการตอบกลับหมายถึงการมีความเข้าใจพื้นฐานเกี่ยวกับเธรดอย่างน้อย - แต่คำตอบนี้ไม่คำนึงถึงบริบทใด ๆ โดยเฉพาะอย่างยิ่งสถานการณ์ที่เป็นแนวคิดที่เลวร้ายมาก เพื่อใช้ Thread.Sleep - เช่นบนเธรด UI
Mike Tours
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.