问题描述
我在 SQL Server 中有一个名为 ParseXML 的存储过程.我有一个使用 LINQ to SQL 的存储库模式.我需要从存储库层中调用存储过程.与 GetTable 方法不同,我们没有用于数据上下文的 GetStoredProcedure 方法.这种情况下如何调用存储过程?
I have a stored procedure named ParseXML in SQL Server. I have a repository pattern using LINQ to SQL. I need to call the stored procedure from within the repository layer. Unlike GetTable method, we don’t have a GetStoredProcedure method for data context. How can we call the stored procedure in such a scenario?
数据库代码
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.ParseXML")] public ISingleResult<ParseXMLResult> ParseXML([global::System.Data.Linq.Mapping.ParameterAttribute(Name="InputXML", DbType="Xml")] System.Xml.Linq.XElement inputXML) { IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), inputXML); return ((ISingleResult<ParseXMLResult>)(result.ReturnValue)); }
存储层
namespace RepositoryLayer { public interface ILijosBankRepository { System.Data.Linq.DataContext Context { get; set; } List<DBML_Project.BankAccount> GetAllAccountsForUser(int userID); void UpdateBankAccountUsingStoredProcedure(); } public class LijosSimpleBankRepository : ILijosBankRepository { public System.Data.Linq.DataContext Context { get; set; } public List<DBML_Project.BankAccount> GetAllAccountsForUser(int userID) { IQueryable<DBML_Project.BankAccount> queryResultEntities = Context.GetTable<DBML_Project.BankAccount>().Where(p => p.AccountOwnerID == userID); return queryResultEntities.ToList(); } public virtual void UpdateBankAccountUsingStoredProcedure() { //Context.GetStroedProcedures(); } } }
参考:
- 多个 UnitOfWorks、ISession 和存储库
推荐答案
让存储库的任何调用者知道特定方法调用是否导致从文件、SQL 读取文本是 SOC 的一个巨大突破语句、sprocs 甚至只是花园侏儒在文本终端上输入结果.
It's a pretty huge break of SOC to have any callers of your repository be aware of whether or not a particular method call results in reading text from a file, SQL statement, sprocs or even just garden gnomes typing results out on a text terminal.
为此,将 Context 属性设为公开无济于事.使用存储库的全部意义在于让消费者免受持久性问题的困扰!
To that end, it doesn't help matters to have your Context property be public. The whole point of using a repository is so that consumers are shielded from persistence concerns!
由于您似乎非常需要避免使用自定义类型的 Context,您可以省去很多麻烦,只需发出一个直接的、老式的 SQL 语句即可执行你的程序.
Since you seem to have a strong need to avoid using a custom-typed Context, you'd save yourself much trouble and just issue a straight-up, old-school SQL statement that will execute your sproc.
考虑重构您的界面和逻辑,使其看起来更像这样:
Consider refactoring your interface and logic to look more like this:
public interface ILijosBankRepository { List<DBML_Project.BankAccount> GetAllAccountsForUser(int userID); void UpdateBankAccount(/* params go here */); /* ...other query methods, etc... */ } public class LijosBankRepository : ILijosBankRepository { private readonly DataContext context { get; set;} public LijosBankRepository(DataContext ctx) { ... } public void UpdateBankAccount(string inputXml) { context.ExecuteCommand("ParseXML", inputXml); } }