简体   繁体   English

将存储过程调用从LINQ数据上下文传递到另一个方法。 C#

[英]Passing a stored procedure call from a LINQ data context to another method. C#

I feel the answer to this may lie with delegates, but I am having a hard time grasping the concept of delegates. 我觉得这可能取决于代表,但我很难理解代表的概念。 The main problem is that every explanation and example of delegates I have ever read are always round about ways of doing something you could accomplish without delegates so to me it does not teach me anything. 主要问题是,我所阅读过的代表的每种解释和示例都总是围绕着没有代表的情况下您可以完成的事情的方式进行的,因此对我而言,它并没有教给我任何东西。 I learn best by seeing real world examples. 通过查看现实世界的例子,我学得最好。

Now that that is out of the way, here is what I want to accomplish. 既然这已经不成问题,这就是我要完成的工作。 I have a Data Context (.dbml) with numerous stored procedures. 我有一个包含大量存储过程的数据上下文(.dbml)。 I also have mutliple situations where I am using the exact same 20 lines of code to update one column in a table, but the only difference other than using a different datagrid, is the stored procedure being called. 我还遇到了多种情况,在这些情况下,我使用完全相同的20行代码来更新表中的一列,但是除了使用不同的datagrid之外,唯一的区别是调用了存储过程。 In an effort of reducing the amount of code used, I was hoping for a way to pass the stored procedure call from the data context object as a parameter. 为了减少使用的代码量,我希望有一种方法可以将来自数据上下文对象的存储过程调用作为参数传递。 That way I can move all that code to one reusable function. 这样,我可以将所有代码移至一个可重用的函数。 Is this even possible? 这有可能吗? I am using Visual Studio 2008 and C#. 我正在使用Visual Studio 2008和C#。

Thanks for any guidance. 感谢您的指导。

While I can't help you with the sql / stored proc side of things, I can try explain delegates, at least from the C# point of view. 尽管我在sql / stored proc方面无能为力,但至少可以从C#的角度来看,我可以尝试解释委托。

While normally you declare functions as being part of a class (and hence they are strongly attached to the class), sometimes you want to put them in a variable. 通常,您将函数声明为类的一部分(因此它们与该类紧密关联),但有时您希望将其放入变量中。 Once you do this, you can then pass it around, much like you would with any other variable. 完成此操作后,就可以像使用任何其他变量一样将其传递。

So we know that a string is the kind of variable that you stick text into. 因此,我们知道字符串是您将文本粘贴到其中的一种变量。 Following that, a delegate is the kind of variable that you stick functions into. 之后,委托就是您将函数插入其中的变量。 This however is very confusing, as C# isn't consistent or clear with how it names things in your code. 但是,这非常令人困惑,因为C#在代码中如何命名事物并不一致或不清楚。 Observe: 注意:

public void WriteText() {
  Console.WriteLine("Hello");
}

...
Action x = WriteText;
x(); // will invoke the WriteText function

Note we're using "Action" where logic would imply the code should read delegate x = WriteText . 注意,我们使用“ Action”,其中逻辑将暗示代码应读取delegate x = WriteText The reason we need this extra mess is because "delegate" itself is like System.Object . 我们之所以需要这些额外的混乱,是因为“委托”本身就像System.Object一样。 It doesn't contain any information, and it's kind of the "base class" behind everything. 它不包含任何信息,它是所有内容背后的“基类”。 If we actually want to use one, we have to attach some Type information. 如果实际上要使用一个,则必须附加一些Type信息。 This is where Action comes in. The definition of Action is as follows: 这是Action进来的定义。 Action如下:

public delegate void Action();

What this code says is "we're declaring a new delegate called Action, and it takes no parameters and returns void ". 这段代码说的是“我们正在声明一个名为Action的新委托, 它不带任何参数并返回void ”。 Thereafter if you have any functions which also take no parameters and return void, you put them in variables of type Action . 此后,如果您有任何也没有参数且返回void的函数,则将它们放在Action类型的变量中。

Now, you can stick a normal function into a delegate, but you can also stick an "anonymous" function into a delegate. 现在,您可以将普通函数放入委托中,但也可以将“匿名”函数放入委托中。 An "anonymous" function is something that you declare inline, so rather than attaching the already-declared WriteText function, we could build a new one up in the middle of our code like this: 您可以内联声明一个“匿名”函数,因此与其附加已经声明的WriteText函数,我们还可以在代码中间构建一个新的函数,如下所示:

Action x = () => { Console.WriteLine("Hello"); };
x(); // invoke our anonymous function.

What this is doing is using the C# "lambda syntax" to declare a new anonymous function. 这是在使用C#“ lambda语法”声明一个新的匿名函数。 The code that runs as part of the function (when we invoke it) is the Console.WriteLine . 作为函数一部分运行的代码(当我们调用它时)是Console.WriteLine

SO 所以

To put it all together, you could have a "SaveData" function, and pass it a delegate. 放在一起,您可以拥有一个“ SaveData”功能,并将其传递给它一个委托。 It could do it's 20 lines of table building, then pass that table to the delegate, and the delegate could invoke the appropriate stored-proc. 它可以完成20行表的构建,然后将该表传递给委托,委托可以调用适当的存储过程。 Here's a simple example: 这是一个简单的例子:

public void SaveData(Action<Table> saveFunc){
    var t = new Table();
    ... 20 lines of code which put stuff into t ...
    saveFunc(t);
}

SaveData( t => StoredProc1.Invoke(t) ); // save using StoredProc1
SaveData( t => StoredProc37.Invoke(t) ); // save using StoredProc37

SO 所以

Having said ALL OF THAT. 说了这么多。 This isn't how I'd actually solve the problem. 这不是我实际解决问题的方式。 Rather than passing the delegate into your savedata function, it would make more sense to have your SaveData function simply return the table, and then you could then invoke the appropriate StoredProc without needing delegates at all 与其将委托传递到savedata函数中,不如让SaveData函数简单地返回表会更有意义,然后您可以调用适当的StoredProc而不需要委托

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

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