我目前正在建立一个系统,其中SQL Server到客户端连接的基本服务器端安全性是通过每个用户的视图实现的(Windows身份验证)。
获得所有数据的主表Entries
DENY SELECT, UPDATE, INSERT, DELETE ON [dbo].[Entries] FOR public
,因此访问用户数据的唯一方法是使用相应的视图ENTRIES_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身份验证,使用Annotations实现对象映射。
我不知道的是,如果此表存在,在尝试Entity().ToTable(...)
之前如何检查。如果它没有,我想调用存储过程,为用户创建一个新视图。
我已经尝试将ToTable
- 调用放在try-catch中,但即使它无法正常连接,也不会导致异常。
如果我要映射的表/视图已经存在,是否有提前检查的方法而不使用硬编码的SQL查询?如果没有,我可以以某种方式在EF映射失败时做出反应,执行某些操作(存储过程调用),然后重试吗?
编辑:我决定用查询手动检查应该没问题,如果没有&#34;清洁&#34;解。有没有办法在OnModelCreating
中获取服务器连接,还是我必须自己创建一个?
答案 0 :(得分:0)
我设法让这个工作,但只有自己的连接。我无法使用现有的,因为DbContext阻止我在OnModelCreating中访问它。
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");
}