ส่งสตริงการเชื่อมต่อไปยัง DbContext รหัสแรก


92

ฉันจะส่งสตริงการเชื่อมต่อไปยัง DbContext รหัสแรกของกรอบเอนทิตีได้อย่างไร การสร้างฐานข้อมูลของฉันทำงานได้อย่างถูกต้องเมื่อทั้ง DbContext และสตริงการเชื่อมต่อใน web.config อยู่ในโปรเจ็กต์เดียวกันและตั้งชื่อในลักษณะเดียวกัน แต่ตอนนี้ฉันต้องการย้าย DbContext ไปยังโปรเจ็กต์อื่นดังนั้นฉันจึงทดสอบส่งสตริงการเชื่อมต่อไปยังมันดังนี้:

โมเดลและบริบท

public class Dinner
{
    public int DinnerId { get; set; }
    public string Title { get; set; }
}

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
        : base(connString)
    {
    }
    public DbSet<Dinner> Dinners { get; set; }
}

หนังบู๊

    public ActionResult Index()
    {
        var db = new NerdDinners(ConfigurationManager.ConnectionStrings["NerdDinnerDb"].ConnectionString);

        var dinners = (from d in db.Dinners
                      select d).ToList();
        return View(dinners);
    }

Web.Config

<connectionStrings>
  <add name="NerdDinnerDb" connectionString="Data Source=|DataDirectory|NerdDinners.sdf" providerName="System.Data.SqlServerCe.4.0"/>    
</connectionStrings>

ถ้าฉันตั้งค่าเบรกพอยต์ในการดำเนินการวิเคราะห์dbสตริงการเชื่อมต่อจะอยู่ที่นั่น แต่ไม่ได้สร้างหรือค้นหาฐานข้อมูลหรืออะไรเลย

เกิดข้อผิดพลาดเกี่ยวกับเครือข่ายหรือเฉพาะอินสแตนซ์ขณะสร้างการเชื่อมต่อกับ SQL Server ไม่พบเซิร์ฟเวอร์หรือไม่สามารถเข้าถึงได้ ตรวจสอบว่าชื่ออินสแตนซ์ถูกต้องและมีการกำหนดค่า SQL Server ให้อนุญาตการเชื่อมต่อระยะไกล (ผู้ให้บริการ: ผู้ให้บริการท่อชื่อข้อผิดพลาด: 40 - ไม่สามารถเปิดการเชื่อมต่อกับ SQL Server)


คุณแน่ใจจริงๆว่ากำลังเชื่อมต่อกับเซิร์ฟเวอร์ที่ถูกต้อง? ข้อผิดพลาดเป็นข้อยกเว้นทั่วไปของ SQL Server / Express ฟังดูไม่เหมือนคุณกำลังเชื่อมต่อกับฐานข้อมูล Sql CE ... และ EF Code ก่อนจะสร้างฐานข้อมูลหากไม่มีอยู่ ... เว้นแต่ว่าอาจไม่พบเส้นทาง ...
Steven K.

โดยพื้นฐานแล้วความผิดพลาดของ OP คือการส่ง connectionstring ทั้งหมดไปยังตัวสร้าง DbContaxt แทนที่จะเป็นแค่ชื่อ ตามที่เอกสารระบุว่า: "DbContext (String) สร้างอินสแตนซ์บริบทใหม่โดยใช้สตริงที่กำหนดเป็นชื่อหรือสตริงการเชื่อมต่อสำหรับฐานข้อมูล"
Göran Roseen

คำตอบ:


86

เล่นเกมช้าไปหน่อย แต่อีกทางเลือกหนึ่งคือ:

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
    {
        this.Database.Connection.ConnectionString = connString;
    }
    public DbSet<Dinner> Dinners { get; set; }
}

2
ไฮ! นี่เป็นทางออกเดียวที่ทำให้ฉันอยู่ที่ไหนสักแห่ง ปัญหาของฉันคือฉันต้องการใช้การตั้งค่าจากไฟล์การกำหนดค่า Azure ของฉันแทน web.config อย่างไรก็ตามวิธีนี้ใช้ไม่ได้เนื่องจากไม่มีการตั้งค่า "ผู้ให้บริการ" (ตั้งเป็นแอตทริบิวต์ใน web.config) ความคิดใด ๆ ?
ผู้ใช้

1
ตอบโจทย์สุด ๆ ! การเปลี่ยนแปลงเพียงอย่างเดียวคือการลบพารามิเตอร์ connString จากนั้นใช้สตริงการเชื่อมต่อที่บันทึกไว้ในการตั้งค่าแอปพลิเคชัน .... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
ประโยชน์ดู

ฉันจะส่งทั้ง connString และ DbCompiledModel object พร้อมกันเป็นพารามิเตอร์ได้อย่างไร
Behzad Ebrahimi

ดี. เพียงแค่ "สิ่งนี้" ซ้ำซ้อนคุณสามารถลบออกได้
tocqueville

1
หากโมดูลชั้นเรียนของคุณรวมManual changes to this file will be overwritten if the code is regenerated.อยู่ในส่วนหัวเราอาจต้องการใช้สิ่งนี้ในคลาสบางส่วนตามคลาสและวิธีการบางส่วน (คู่มือการเขียนโปรแกรม C #)
woodvi

59

หลังจากอ่านเอกสารฉันต้องส่งชื่อของสตริงการเชื่อมต่อแทน:

var db = new NerdDinners("NerdDinnerDb");

ฉันใส่สิ่งนั้นไว้ในตัวสร้างของฉันและทำให้มันเป็นค่าคงที่สาธารณะในกรณีที่จำเป็นสำหรับการอ้างอิงที่อื่น
Tony Wall

37

คิดว่าฉันจะเพิ่มบิตนี้สำหรับผู้ที่กำลังมองหา "วิธีส่งสตริงการเชื่อมต่อไปยัง DbContext": คุณสามารถสร้างสตริงการเชื่อมต่อสำหรับที่เก็บข้อมูลพื้นฐานของคุณและส่งสตริงการเชื่อมต่อทั้งหมดไปยังตัวสร้างประเภทของคุณที่ได้รับจาก DbContext .

(ใช้โค้ดซ้ำจาก @Lol Coder) โมเดลและบริบท

public class Dinner
{
    public int DinnerId { get; set; }
    public string Title { get; set; }
}

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
        : base(connString)
    {
    }
    public DbSet<Dinner> Dinners { get; set; }
}

จากนั้นสมมติว่าคุณสร้างสตริงการเชื่อมต่อ Sql โดยใช้ SqlConnectioStringBuilder ดังนี้:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

โดยที่เมธอด GetConnectionString สร้างสตริงการเชื่อมต่อที่เหมาะสมและ SqlConnectionStringBuilder ทำให้แน่ใจว่าสตริงการเชื่อมต่อถูกต้องตามหลักไวยากรณ์ จากนั้นคุณสามารถสร้างอินสแตนซ์ฐานข้อมูลของคุณได้ดังนี้:

var myContext = new NerdDinners(builder.ToString());

4
ในการเข้ารหัสสตริงการเชื่อมต่อที่ยากมากฉันทำ:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }
Elijah W. Gagne

28

ใน DbContext ของคุณสร้างตัวสร้างเริ่มต้นสำหรับ DbContext ของคุณและสืบทอดฐานดังนี้:

    public myDbContext()
        : base("MyConnectionString")  // connectionstring name define in your web.config
    {
    }

1
ในกรณีของฉันมันสร้าง DB ชื่อMyConnectionString... (ใช่มีสตริงการเชื่อมต่ออยู่) name=MyConnectionStringฉันต้องใส่
Matthieu Charbonnier

2

หากคุณกำลังสร้างสตริงการเชื่อมต่อภายในแอพคุณจะต้องใช้คำสั่ง connString หากคุณใช้สตริงการเชื่อมต่อในการกำหนดค่าเว็บ จากนั้นคุณใช้ "ชื่อ" ของสตริงนั้น


2

ฉันมีตัวอย่างวิธีแก้ปัญหาเล็กน้อยสำหรับปัญหานั้น

MyDBContext.cs

 public MyDBContext(DBConnectionType ConnectionType) //: base("ConnMain")
  {
      if(ConnectionType==DBConnectionType.MainConnection)
       {
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnMain"].ConnectionString;
       }
      else if(ConnectionType==DBConnectionType.BackupConnection)
       {
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnBackup"].ConnectionString;
       }
  }

MyClass.cs

public enum DBConnectionType
 {
    MainConnection=0,
    BackupConnection=1
 }

frmMyForm.cs

 MyDBContext db = new MyDBContext(DBConnectionType.MainConnection);
                               //or
//MyDBContext db = new MyDBContext(DBConnectionType.BackupConnection);

1

ตรวจสอบไวยากรณ์ของสตริงการเชื่อมต่อของคุณใน web.config มันควรจะเป็นสิ่งที่ชอบConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"


สตริงการเชื่อมต่อจะทำงานเมื่อทั้งคู่ใช้ชื่อเดียวกันในโปรเจ็กต์เดียวกัน
Shawn Mclean

ไม่ได้ผลเมื่อฉันต้องการส่งต่อไปยัง DbConext ด้วยตนเอง
Shawn Mclean

สตริงการเชื่อมต่อนั้นใช้ได้เส้นทางไม่จำเป็นต้องเป็นแบบสัมบูรณ์
Steven K.

1

เมื่อใช้โมเดล EF ฉันมีสตริงการเชื่อมต่อในแต่ละโปรเจ็กต์ที่ใช้โมเดล EF ตัวอย่างเช่นฉันมีโมเดล EF EDMX ในไลบรารีคลาสแยกต่างหาก ฉันมีสตริงการเชื่อมต่อหนึ่งสายในโปรเจ็กต์เว็บ (mvc) ของฉันเพื่อให้สามารถเข้าถึง EF db

ฉันยังมีโครงการทดสอบหน่วยอื่นสำหรับการทดสอบที่เก็บ เพื่อให้ที่เก็บเข้าถึง EF db ไฟล์ app.config ของโปรเจ็กต์ทดสอบจะมีสตริงการเชื่อมต่อเดียวกัน

ควรกำหนดค่าการเชื่อมต่อ DB ไม่ใช่เข้ารหัส IMO


2
ฉันต้องการส่งผ่านสตริงการเชื่อมต่อด้วยตนเองด้วยรหัส ฉันใช้การฉีดแบบพึ่งพา
Shawn Mclean


0

ไม่เห็นอะไรผิดปกติกับรหัสของคุณฉันใช้ SqlExpress และทำงานได้ดีเมื่อฉันใช้สตริงการเชื่อมต่อในตัวสร้าง

คุณได้สร้างโฟลเดอร์ App_Data ในโครงการของคุณแล้วใช่หรือไม่


0

สำหรับใครก็ตามที่มาที่นี่เพื่อลองค้นหาวิธีตั้งค่า dinamicaly สตริงการเชื่อมต่อและมีปัญหากับแนวทางแก้ไขด้านบน (เช่น "รูปแบบของสตริงการเริ่มต้นไม่เป็นไปตามข้อกำหนดที่เริ่มต้นที่ดัชนี 0") เมื่อตั้งค่าสตริงการเชื่อมต่อใน ผู้สร้าง นี่คือวิธีแก้ไข:

public static string ConnectionString
{
    get {
        if (ConfigurationManager.AppSettings["DevelopmentEnvironment"] == "true")
            return ConfigurationManager.ConnectionStrings["LocalDb"].ConnectionString;
        else
            return ConfigurationManager.ConnectionStrings["ExternalDb"].ConnectionString;
    }
}

public ApplicationDbContext() : base(ConnectionString)
{
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.