C#跨程序访问VS2015创建的单表mdf数据库时查询执行失败
问题场景
在DB_Write程序中创建的单表MDF数据库可正常访问、查询数据,尝试通过另一个简易C#程序DB_Read读取操作该数据库数据时,DB_Read可通过配置的connectionString成功定位数据库并打开连接,但执行var DatabaseExists = context.data.Any();语句时始终报错,排查多日未定位到根因。DB_Read项目中的数据库实体类、数据库上下文、字段列名均从DB_Write项目直接复制,完整代码如下:
using System; using System.Data; using System.Linq; using System.Windows.Forms; using System.Data.Entity; using System.ComponentModel.DataAnnotations; using System.Data.SqlClient; namespace DB_Read { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public class TestDB { [Key]public int Index { get; set; } public string Letter { get; set; } public Double WTime { get; set; } } public class TestDB_Context : DbContext { public DbSet<TestDB> data { get; set; } } private void btnSum_Click(object sender, EventArgs e) { string connectionString; SqlConnection cnn; connectionString = @"Data Source=(localdb)\mssqllocaldb; Initial Catalog=DB_Write.Form1+TestDB_Context; Integrated Security=True"; cnn = new SqlConnection(connectionString); cnn.Open(); using (var context = new TestDB_Context()) { var DatabaseExists = context.data.Any(); if(DatabaseExists == true) { var query = (from column3 in context.data select column3.WTime).Sum(); txtResult.Text = Convert.ToString(query); } } cnn.Close(); } } }
核心问题点
- 手动创建的
SqlConnection对象与EF上下文完全无关:代码中手动实例化SqlConnection、执行打开/关闭连接的操作没有任何实际作用,TestDB_Context实例化时没有传入任何连接参数,EF会使用默认规则加载连接字符串,根本不会连接到你预期的目标数据库。 - 未关闭EF默认的数据库初始化策略:EF Code First默认会检查连接的数据库是否匹配当前模型,不匹配时会尝试创建新数据库、抛出迁移相关错误,不会直接读取已有数据库中的数据。
- 连接字符串配置缺失:仅指定
Initial Catalog没有指定AttachDbFilename指向MDF文件的实际物理路径时,LocalDB会在当前程序的运行上下文下查找对应名称的数据库,无法定位到DB_Write程序生成的MDF文件。
修复方案
- 删除无效的手动
SqlConnection创建、打开、关闭代码,EF会自行管理数据库连接的生命周期,不需要手动干预。 - 改造
TestDB_Context类,增加带连接字符串参数的构造函数,同时关闭EF默认的数据库初始化逻辑,代码如下:
public class TestDB_Context : DbContext { public TestDB_Context(string connStr) : base(connStr) { // 禁用建库、迁移检查逻辑,直接使用现有数据库 Database.SetInitializer<TestDB_Context>(null); } public DbSet<TestDB> data { get; set; } }
- 修正连接字符串,显式指定MDF文件的完整物理路径,示例:
string connectionString = @"Data Source=(localdb)\mssqllocaldb; AttachDbFilename=C:\实际存放路径\你的数据库文件.mdf; Integrated Security=True; Connect Timeout=30";
- 实例化上下文时传入修正后的连接字符串,将原有
using (var context = new TestDB_Context())修改为:
using (var context = new TestDB_Context(connectionString)) { var DatabaseExists = context.data.Any(); if(DatabaseExists) { var query = context.data.Sum(x => x.WTime); txtResult.Text = query.ToString(); } }
内容的提问来源于stack exchange,提问作者Pete
相关产品推荐
相关产品推荐

