C# 带存储过程的多租户EF实现
你好 我在实体框架中为我的所有CRUD方法使用存储过程。因为这是一个多租户数据库,所以每个表中都有一个clientID字段。我们的DBA不希望该clientID被公开,因此我们将用户名传递到存储过程(已验证用户的用户名,在成员资格提供程序中跟踪),然后存储过程在存储过程内部处理用户名到clientID的转换 我遇到的问题是,我的实体没有Username属性。当我为insert/update/delete创建函数导入时,映射正在请求一个用户名字段(必需,来自存储过程),该字段在我的实体中不存在。以下是我的模式: 账户主体 帐号C# 带存储过程的多租户EF实现,c#,entity-framework,C#,Entity Framework,你好 我在实体框架中为我的所有CRUD方法使用存储过程。因为这是一个多租户数据库,所以每个表中都有一个clientID字段。我们的DBA不希望该clientID被公开,因此我们将用户名传递到存储过程(已验证用户的用户名,在成员资格提供程序中跟踪),然后存储过程在存储过程内部处理用户名到clientID的转换 我遇到的问题是,我的实体没有Username属性。当我为insert/update/delete创建函数导入时,映射正在请求一个用户名字段(必需,来自存储过程),该字段在我的实体中不存在。以
帐户说明
客户ID
ActiveFlag
行版本(用于并发) 还有我的狂欢:
ALTER PROCEDURE [dbo].[GetAccounts]
@Username varchar (60)
AS
/*********************************************
Summary: Get Accounts
2011-01-20 aca initial version
2011-01-27 aca Alias for Description
2011-03-21 aca Implement user security
********************************************/
select P.FERC_ACCOUNT,
P.[DESCRIPTION] as AccountDescription,
P.RowVersion
from dbo.P_ACCOUNTS P
join dbo.v_UserClient U
on U.Username = @Username
and P.CLIENT_ID = U.Client_ID
where P.ActiveFlag = 1;
RETURN 0;
我不确定最好的方法是什么。我是否只在实体中创建用户名属性?那意味着我必须对每个人都这样做?如何填充它?等等:)
谢谢你的帮助
Scott我有相同的限制,我将存储过程导出为函数。对于没有输出参数的过程,我返回默认生成的复杂类型,即GetAccountsResult
public IEnumerable<GetAccountsResult> GetAccounts(string username)
{
return ObjectContext.GetAccounts(username).AsQueryable();
}
对于具有输出参数的过程,我创建一个包含输出参数属性的poco对象和另一个匹配复杂类型的poco对象。然后,我使用AutoMapper将返回的复杂类型映射到我创建的复杂类型。我这样做是为了返回关系
Account.cs
public class Account
{
[Key]
public int Id { get; set; }
public string MyOutputParameter { get; set; }
[Include, Association("Account_AccountDetails", "Id", "AccountId")]
public List<AccountDetail> AccountDetails { get; set; }
}
AccountDomainService.cs
public Account GetAccountsWithOutputParms(string username)
{
var myOutputParameter = new ObjectParameter("MyOutPutParameter", typeof(int));
var tempGetAccountsResult = ObjectContext.GetAccounts(username).ToList();
var account = new Account
{
Id = 1,
MyOutputParameter = myOutputParameter,
AccountDetails = Mapper.Map<List<GetAccountsResult>, List<AccountDetail>>(tempGetAccountsResult)
};
return accout;
}
公共帐户GetAccountsWithOutputParms(字符串用户名)
{
var myOutputParameter=新的ObjectParameter(“myOutputParameter”,typeof(int));
var tempGetAccountsResult=ObjectContext.GetAccounts(用户名).ToList();
var账户=新账户
{
Id=1,
MyOutputParameter=MyOutputParameter,
AccountDetails=Mapper.Mapper您可以通过分部类添加它吗?我当然知道分部类是什么(我的域服务被分解为每个实体集的一个分部类,以适应更新我的模型,然后不必更新构成我的ds的所有200个方法),但你能解释一下我是如何实现的以及为什么吗?这是一个SL项目吗?你是将实体映射到进程还是直接调用导出的函数。是的,SL4,C#,MVVM Light。我有一个实体,它是我的帐户表,它只有AccountNumber,AccountDescription,clientID。然后我将insert/update/delete存储过程映射到那个ent在这个映射过程中,我遇到了将存储过程用户名字段映射到帐户实体的要求。我还有一个GetAccounts存储过程,我想我必须在我的GetAccounts()中直接调用它由我的domainservice创建的方法。我可能会创建一个表示存储过程所需内容的poco实体,并将一个或一个列表传递到导出的domainservice函数中。这听上去肯定是正确的答案,所以我要将其标记为正确的。该链接中的站点已关闭,我基本上要到今天早上才能移动是否继续EF。我以前没有使用过AutoMapper,我需要做更多的研究来理解你说要做的一些事情,我根本没有时间去做。我感谢你的帮助…当我有更多的带宽时,我肯定会重新讨论这个问题。谢谢Derek。AutoMapper不是必须的。你可以将一个对象映射到一个对象没有它。如果你有更多的问题,我们可以把它发送到电子邮件。derek.beattie在gmail。对我来说,它仍然不起作用,可能是防火墙或工作中的代理。今晚我会在家里看一看。我也会在某个时候给你发一封电子邮件,谢谢。我很想弄明白这一点——用服务器端模型编写asmx web服务,db access layers和客户端模型/服务很快就会过时。感谢您的帮助。
public class AccountDetail
{
[Key]
public int Id { get; set; }
public int AccountId { get; set; }
public string MyAccountDetailProperty { get; set; }
}
public Account GetAccountsWithOutputParms(string username)
{
var myOutputParameter = new ObjectParameter("MyOutPutParameter", typeof(int));
var tempGetAccountsResult = ObjectContext.GetAccounts(username).ToList();
var account = new Account
{
Id = 1,
MyOutputParameter = myOutputParameter,
AccountDetails = Mapper.Map<List<GetAccountsResult>, List<AccountDetail>>(tempGetAccountsResult)
};
return accout;
}