我最近将我的一个项目更新到Visual Studio 2013.更新将我的.dbproj更改为.sqlproj,使其符合新的SQL项目格式.
在转换之后,我运行了一个与我的SQL项目和我的SQL 2008生产数据库进行模式比较,它现在认为每个对象都是不同的.通过模式比较工具进行调查后,看来差异在于每个对象定义还包括为该对象授予每个角色或用户的权限的语句.
因此,服务器端看起来像这样:
CREATE PROC MyCoolProc
BEGIN
--some code
END
GO
GRANT EXECUTE
ON OBJECT MyCoolProc TO MyAwesomeUser
AS [Schema];
GO
Run Code Online (Sandbox Code Playgroud)
并且同一对象的客户端看起来像这样:
CREATE PROC MyCoolProc
BEGIN
--some code
END
Run Code Online (Sandbox Code Playgroud)
为什么是这样?当我使用Visual Studio 2010运行模式比较时没有发生这种情况.此外,我查看了SQL比较工具的所有选项,但我找不到"忽略对象的权限声明".有人可以帮忙吗?
编辑
为了确保这是Visual Studio的SQL Compare工具而不是SQL Server本身的问题,我在我的登台和生产数据库之间重新运行Visual Studio 2010中的比较,并且对象定义不像他们那样包含对象权限在Visual Studio 2013中.
sql-server-2008 database-schema schema-compare visual-studio-2013 sqlproj
背景
我正在将项目中的LINQ-to-SQL代码更改为Entity Framework.大部分的转变都相对简单,但是,我遇到了一个相当重要的问题.使用LINQ-to-SQL,我能够使用如下存储过程加载整个对象图(对于模型B):
ViewModel.Model = MyDbContext.usp_ModelA_GetByID(AId).Single();
List<ModelB> Details =
(from b in MyDbContext.usp_ModelB_GetByID(BId)
join c in MyDbContext.usp_ModelC_GetAll()
on b.CId equals c.CId
select new ModelB()
{
BId = b.BId,
CId = b.CId,
C = c
}).ToList();
ViewModel.Model.ModelBs.AddRange(Details);
Run Code Online (Sandbox Code Playgroud)
但是,在将此代码转换为EF后,在访问ViewModel.Model.ModelBs的行上,我得到错误"EntityCommandExecutionException",内部异常解释"对象'ModelBTable'上的SELECT权限被拒绝." 显然,EF正在尝试为ModelA获取ModelB,即使我已经从数据库中加载了它们.虽然我不完全理解为什么它试图加载实体,即使我已经添加它们,我只能假设因为它本身没有加载它们,它不相信它们是完全加载的并且可能会查看所有的对象我作为"新"加载到它.
为了绕过EF试图获取对象本身,我决定将我的代码更改为:
ViewModel.Model = MyDbContext.usp_ModelA_GetByID(AId).Single();
List<ModelB> Details =
(from b in MyDbContext.usp_ModelB_GetByID(BId)
join c in MyDbContext.usp_ModelC_GetAll()
on b.CId equals c.CId
select new ModelB()
{
BId = b.BId,
CId = c.CId,
C = c
}).ToList();
ViewModel.Model.ModelBs = new EntityCollection<ModelB>();
foreach (ModelB detail in Details) …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个概念验证,我在其中编写了一个模块(让我们说这个讨论的目的论坛)遵循领域驱动设计指南,并且将有一个可插拔的存储库,整个模块可以在Web服务器本地插入(本地托管的dll)或通过WCF服务.
遵循域驱动设计指南,我会有一组业务对象,可以像这样编写:
public class Forum
{
readonly IRepository _forumRepository;
public Forum(IRepository forumRepository)
{
_forumRepository = forumRepository;
}
public string Name { get; set; }
public void Save()
{
_forumRepository.SaveForum(this);
}
}
Run Code Online (Sandbox Code Playgroud)
假设Web应用程序需要创建一个新论坛.
如果模块通过dll文件本地托管,这一切都很好.Web应用程序代码将简单地使用Ninject(或任何DI)来实例化业务对象并调用Save方法.
但是,如果实施者想在两者之间引入服务层呢?假设他们想在应用程序和数据库层之间引入WCF服务层,因为他们希望物理架构是Web Server - > App Server - > DB Server.显然,论坛模块dll将由Web服务器和应用服务器托管.但是,该模块不再可用.
如果Web服务器使用存储库注入实例化对象并将其传递到WCF服务层,则即使我允许将业务对象序列化,_forumRepository字段也会丢失.
实现者应该能够让应用服务器选择存储库.那么,有了这个要求,在从Web服务器接收到已经实例化的对象之后,实现者如何在应用服务器端注入存储库?有没有办法告诉WCF服务在反序列化过程中实例化对象时注入存储库?
我阅读了文章,如何在WCF服务中使用依赖注入(Ninject),并查看了示例解决方案,但这仅演示了如何将存储库直接注入服务.它似乎没有解决我在这里讨论的问题.
以下是我如何正确编写代码的例子.正如我之前所说,这里的主要问题是我不知道如何将存储库注入服务端的域对象.
应用程序代码(Web App或Windows App):
Forum newForum = new Forum();
//Set some properties on newForum.
IKernel kernel = new StandardKernel(); //Instantiate ninject kernel.
//Yes, I know using the using statement means that IService …Run Code Online (Sandbox Code Playgroud)