得到数据上下文存储过程:LINQ to SQL的上下文、存储过程、数据、SQL

2023-09-04 00:21:30 作者:无法言说的痛

我有一个名为ParseXML在SQL Server存储过程。我使用LINQ to SQL存储库模式。我需要从资源库层中调用存储过程。不同于 GetTable 方式,我们没有一个 GetStoredProcedure 方式进行数据上下文。我们怎么能说在这样的情况下存储过程?

DBML code

  [全球:: System.Data.Linq.Mapping.FunctionAttribute(NAME =dbo.ParseXML)

    公共ISingleResult< ParseXMLResult> ParseXML([全球:: System.Data.Linq.Mapping.ParameterAttribute(NAME =InputXML的DbType =XML)System.Xml.Linq.XElement inputXML)
    {
        IExecuteResult结果= this.ExecuteMethodCall(这一点,((MethodInfo的)(MethodInfo.GetCurrentMethod())),inputXML);
        返回((ISingleResult< ParseXMLResult>)(result.ReturnValue));
    }
 

库层

 命名空间RepositoryLayer
{
公共接口ILijosBankRepository
{
    System.Data.Linq.DataContext上下文{获得;组; }
    名单< D​​BML_Project.BankAccount> GetAllAccountsForUser(INT用户ID);
    无效UpdateBankAccountUsingStoredProcedure();

}

公共类LijosSimpleBankRepository:ILijosBankRepository
{
    公共System.Data.Linq.DataContext上下文
    {
        得到;
        组;
    }


    公开名单< D​​BML_Project.BankAccount> GetAllAccountsForUser(INT用户ID)
    {
        IQueryable的< D​​BML_Project.BankAccount> queryResultEntities = Context.GetTable< D​​BML_Project.BankAccount>(),其中(P => p.AccountOwnerID ==用户ID);
        返回queryResultEntities.ToList();
    }


    公共虚拟无效UpdateBankAccountUsingStoredProcedure()
    {
        //Context.GetStroedProcedures();
    }

}

}
 

参考文献:

Multiple UnitOfWorks,的ISession和仓库 解决方案

这是SOC的pretty的巨大突破有你的资料库中的任何来电者知道是否有特定的方法调用的结果从阅读文本文件,SQL语句,存储过程,甚至只是花园侏儒型结果出来一个文本终端。

为此,它并不能帮助事情让你的上下文属性是公共的。使用存储库的整点是让消费者从持久性的担忧屏蔽!

既然你似乎有强烈的需求,以避免使用自定义类型的上下文,你会救自己的麻烦,只是发出一个直线上升,OLD-学校的SQL语句,将执行你的存储过程。

考虑重构你的界面和逻辑看起来更像是这样的:

 公共接口ILijosBankRepository
{
    名单< D​​BML_Project.BankAccount> GetAllAccountsForUser(INT用户ID);
    无效UpdateBankAccount(/ * PARAMS到这里* /);
    / * ...等查询方式,等等... * /

}
公共类LijosBankRepository:ILijosBankRepository
{
     私人只读DataContext的情况下{获得;组;}
     公共LijosBankRepository(DataContext的CTX){...}

     公共无效UpdateBankAccount(字符串inputXml)
     {
          context.ExecuteCommand(ParseXML,inputXml);
     }

}
 
LINQ TO SQL 介绍 定义数据模型类 – Part.2

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?

Dbml Code

[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:

Multiple UnitOfWorks, ISession and repositories

解决方案

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.

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!

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

}