使用Entity Framework连接Azure SQL数据库遇SqlException求助
先梳理下你的场景:你部署了一个基于Entity Framework数据库优先(.EDMX)模式的Web应用,初始连接字符串如下:
<add name="Entities" connectionString="metadata=res://*/FdaSecOpsModel.csdl|res://*/FdaSecOpsModel.ssdl|res://*/FdaSecOpsModel.msl;provider=System.Data.SqlClient;provider connection string="data source=....database.windows.net,1433;initial catalog=DEV01;integrated security=True;User ID=username;Password=password;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
你先后遇到了三个错误,我逐个帮你分析原因和解决办法:
第一个错误:Windows登录不支持
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: Windows logins are not supported in this version of SQL Server.
这个问题很明确:你用的是Azure SQL数据库(从连接字符串里的....database.windows.net能看出来),Azure SQL不支持Windows集成身份验证,必须使用SQL Server身份验证。所以你移除Integrated Security=true;的操作是对的,但后续错误是因为连接字符串的使用或配置出了问题。
第二个错误:不支持'metadata'关键字
System.ArgumentException: Keyword not supported: 'metadata'.
这个错误大概率是因为你把EF专属的EntityClient连接字符串当成了普通SqlClient连接字符串来使用了。举两个常见场景:
- 如果你的代码里直接用
SqlConnection去连接,那它只认识常规的SQL连接字符串(就是你连接字符串里provider connection string=后面包裹的部分),不认识metadata这类EF特有的关键字。 - 如果你的DbContext没有正确指定使用这个EntityClient连接字符串,比如构造函数里没传连接字符串名称,或者误把providerName改成了
System.Data.SqlClient。
解决办法:
- 确保DbContext的构造函数正确引用配置文件中的EntityClient连接字符串:
public class FdaSecOpsEntities : DbContext { public FdaSecOpsEntities() : base("name=Entities") { // name=Entities 对应配置文件里<add name="Entities"...>的连接字符串 } }
- 如果需要单独用SqlConnection连接数据库,要提取出
provider connection string里的内容作为连接字符串:
data source=....database.windows.net,1433;initial catalog=DEV01;User ID=username;Password=password;MultipleActiveResultSets=True;App=EntityFramework
第三个错误:无法加载元数据资源
System.Data.Entity.Core.MetadataException: Unable to load the specified metadata resource.
这是EDMX模式下非常常见的元数据加载问题,主要是元数据文件(csdl/ssdl/msl)的嵌入或路径匹配出了问题,按以下步骤排查:
检查EDMX文件属性
右键你的EDMX文件 → 选择「属性」:- 确保「生成操作」设置为
EntityDeploy - 确保「元数据艺术品处理」设置为
嵌入的资源
- 确保「生成操作」设置为
修正连接字符串中的metadata路径
你的连接字符串里用了res://*/,它表示自动在当前程序集中查找元数据文件,但如果EDMX是在类库项目里,或者程序集名称和元数据文件的命名空间不匹配,就会找不到。可以改成指定具体程序集名称的路径,比如你的Web应用程序集叫FdaSecOpsWeb:metadata=res://FdaSecOpsWeb/FdaSecOpsModel.csdl|res://FdaSecOpsWeb/FdaSecOpsModel.ssdl|res://FdaSecOpsWeb/FdaSecOpsModel.msl;...清理并重新生成解决方案
右键解决方案 → 「清理解决方案」,然后删除项目的bin和obj文件夹,再重新生成。旧的元数据缓存很容易导致加载失败,这样能确保最新的元数据资源被嵌入到程序集中。检查元数据文件的命名
确认EDMX生成的csdl/ssdl/msl文件名和连接字符串里的FdaSecOpsModel完全一致,没有拼写错误。
额外验证步骤
- 先用SSMS或者简单的控制台程序测试provider connection string部分,确认能正常连接到Azure SQL,排除用户名、密码、服务器地址、数据库名称的问题。
- 检查Azure SQL服务器的防火墙设置:如果是部署到Azure App Service,要开启「允许Azure服务和资源访问此服务器」;如果是本地部署,要把你的本地IP添加到防火墙规则里。
按上面的步骤逐一排查,应该能解决你的问题。
内容的提问来源于stack exchange,提问作者Mukil Deepthi

