简体   繁体   English

从数据上下文获取存储过程:Linq到SQl

[英]Get Stored Procedure from Data Context : Linq to SQl

I have a stored procedure named ParseXML in SQL Server. 我在SQL Server中有一个名为ParseXML的存储过程。 I have a repository pattern using LINQ to SQL. 我有一个使用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. GetTable方法不同,我们没有针对数据上下文的GetStoredProcedure方法。 How can we call the stored procedure in such a scenario? 如何在这种情况下调用存储过程?

Dbml Code Dbml代码

[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));
    }

Repository Layer 存储库层

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();
    }

}

}

REFERENCE: 参考:

  1. Multiple UnitOfWorks, ISession and repositories 多个UnitOfWorks,ISession和存储库

You can do something like this, calling the method using reflection: 您可以执行以下操作,使用反射调用方法:

var inputXML = GetXML(); 

var method = Context.GetType().GetMethod("ParseXML");

if(method == null) throw new InvalidOperationException("Defined DataContext does not have method ParseXML");

var result = method.Invoke(Context, new object[]{ inputXML });

If you are using c# 4.0, you can do: 如果您使用的是c#4.0,则可以执行以下操作:

var inputXML = GetXML(); 

dynamic dynamicContext = Context;

var result = (ISingleResult<ParseXMLResult>)dynamicContext.ParseXML(inputXML);

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. 让你的存储库的任何调用者知道特定的方法调用是否导致从文件,SQL语句,sprocs甚至只是在文本终端输入结果的花园侏儒中读取文本,这是SOC的一个非常大的突破。

To that end, it doesn't help matters to have your Context property be public. 为此,将Context属性公开无关紧要。 The whole point of using a repository is so that consumers are shielded from persistence concerns! 使用存储库的重点是让消费者免受持久性问题的困扰!

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. 由于您似乎非常需要避免使用自定义类型的Context ,因此您可以省去很多麻烦,只需发出一个直接的,旧式的SQL语句来执行您的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);
     }

}

The C# wrapper is part of your custom DataCcontext derived class. C#包装器是自定义DataCcontext派生类的一部分。 You would call like this: 你会这样打电话:

public virtual void UpdateBankAccountUsingStoredProcedure()
{
    var results = Context.ParseXML(...);
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM