实体框架模型创建 - 检查缺少的数据库对象
本文关键字:数据库 对象 检查 框架 模型 创建 实体 | 更新日期: 2023-09-27 18:36:08
我目前正在设置一个系统,其中SQL服务器到客户端连接的基本服务器端安全性是通过每个用户的视图(Windows身份验证)实现的。
保存所有数据的主表Entries
DENY SELECT, UPDATE, INSERT, DELETE ON [dbo].[Entries] FOR public
,因此访问用户数据的唯一方法是使用其相应的视图ENTRIES_USER
("User"是一个占位符),它显式获得
GRANT SELECT, INSERT, UPDATE, DELETE ON [dbo].[Entries_USER] TO [DOMAIN'user]
.此外,public
的默认权限也会减少,因此没有其他人可以从视图中读取。到目前为止一切正常,现在来了很酷的东西。
我使用实体框架和"CodeFirst"(它在现有数据库上,但映射在运行时发生)连接到此数据库,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Entry>().ToTable("Entries_" + Environment.UserName.ToUpper());
modelBuilder.Entity<Project>().ToTable("Projects");
}
连接字符串启用 Windows 身份验证,对象映射通过注释实现。
我不知道的是,在尝试Entity().ToTable(...)
这个表是否存在之前如何检查。如果没有,我想调用一个存储过程,为 user.
创建一个新视图我已经尝试将ToTable
-Call 放入 try-catch 中,但即使它无法正确连接,这也不会导致异常。
有没有办法在不使用硬编码 SQL 查询的情况下提前检查我要映射到的表/视图是否已经存在?如果没有,当 EF 映射失败时,我是否可以以某种方式做出反应,执行一些操作(存储过程调用),然后重试?
编辑:如果没有"干净"的解决方案,我决定手动检查查询应该没问题。有没有办法在OnModelCreating
中获取服务器连接,还是我必须自己创建一个?
我设法让它工作,但只能通过自己的连接。我不能使用现有的,因为 DbContext 阻止我在 OnModelCreation 中访问它。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
string viewname = "Entries_" + Environment.UserName.ToUpper();
using (SqlConnection connection = new SqlConnection())
using (SqlCommand initCmd = new SqlCommand("IF NOT EXISTS(select * FROM sys.views where name = @ViewName) exec dbo.spAddUser @User, @Domain", connection))
{
// the connection string is the same one I use to create the DbContext
connection.ConnectionString = ConfigurationManager.ConnectionStrings["AppConnectionString"].ConnectionString;
initCmd.Parameters.AddWithValue("ViewName", viewname);
initCmd.Parameters.AddWithValue("User", Environment.UserName);
initCmd.Parameters.AddWithValue("Domain", GetDomain());
try
{
connection.Open();
initCmd.ExecuteNonQuery();
}
catch (SqlException e)
{
Debug.WriteLine(e.Message);
// TODO
}
}
modelBuilder.Entity<Entry>().ToTable(viewname);
modelBuilder.Entity<Project>().ToTable("Projects");
}