1

I have three methods in my datacontext class which all call slightly different stored procedures having different behaviours; APPEND, UPDATE, OVERWRITE. However all three methods have in essence the same code. The only difference is the "Name" property of the System.Data.Linq.Mapping.FunctionAttribute which decorates the methods.

[Function(Name = "import.usp_MyData_ProcessImportAppend", IsComposable = false)]

or

[Function(Name = "import.usp_MyData_ProcessImportUpdate", IsComposable = false)]

or

[Function(Name = "import.usp_MyData_ProcessImportOverwrite", IsComposable = false)]

In essence they all look similar to this

/// <summary>
/// Processes the import.
/// </summary>
/// <param name="loadId">The load id.</param>
/// <exception cref="System.ArgumentNullException">loadId</exception>
[Function(Name = "import.usp_MyData_ProcessImportAppend", IsComposable = false)]
public Int32 ProcessGradingImport(string loadId)
{
    // Validate parameter
    if (String.IsNullOrEmpty(loadId)) throw new ArgumentNullException("loadId");

    // Initialise the result and the procedure parametes
    Int32 result = 0;
    object[] parameters = { loadId };

    // Call the procedure, and return the result
    IExecuteResult executionResult = ExecuteMethodCall(this, (MethodInfo)(MethodBase.GetCurrentMethod()), parameters);
    if (executionResult != null) result = (int)executionResult.ReturnValue;
    return result;
}

Is there any way I can write a generic method where the function name to map to is passed in? Thank you.

UPDATE So based upon the excellent solutions by Ron and Alex, I now have

/// <summary>
/// Process imports.
/// </summary>
/// <param name="methodInfo">The method information.</param>
/// <param name="loadId">The load identifier.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">loadId</exception>
private Int32 ProcessImport(MethodInfo methodInfo, string loadId)
{
    // Validate parameter
    if (String.IsNullOrEmpty(loadId)) throw new ArgumentNullException("loadId");

    // Initialise the result and the procedure parametes
    Int32 result = 0;
    object[] parameters = { loadId };

    // Call the procedure, and return the result
    IExecuteResult executionResult = ExecuteMethodCall(this, methodInfo, parameters);
    if (executionResult != null) result = (int)executionResult.ReturnValue;
    return result;
}

called in decorated function like...

[Function(Name = "common.usp_MyData_ProcessImportAppend", IsComposable = false)]
public Int32 ProcessImportAddNewUpdateCurrentOnly(string loadId)
{
    return ProcessImport((MethodInfo)(MethodBase.GetCurrentMethod()), loadId);
}
4

2 回答 2

2

我会为代码重用做这样的事情:

[Function(Name = "import.usp_MyData_ProcessImportAppend", IsComposable = false)]
public Int32 ProcessGradingImport(string loadId)
{
    ProcessLoadId(loadId, (MethodInfo)(MethodBase.GetCurrentMethod(), new object[] { loadId });
}

[Function(Name = "import.usp_MyData_ProcessImportUpdate", IsComposable = false)]
public Int32 ProcessGradingImportUpdate(string loadId)
{
    ProcessLoadId(loadId, (MethodInfo)(MethodBase.GetCurrentMethod(), new object[] { loadId });
}

[Function(Name = "import.usp_MyData_ProcessImportOverwrite", IsComposable = false)]
public Int32 ProcessGradingImportOverwrite(string loadId)
{
    ProcessLoadId(loadId, (MethodInfo)(MethodBase.GetCurrentMethod(), new object[] { loadId });
}

public Int32 ProcessLoadId(string loadId, MethodInfo method, object[] parameters)
{
    // Validate parameter
    if (String.IsNullOrEmpty(loadId)) throw new ArgumentNullException("loadId");

    // Initialise the result and the procedure parametes
    Int32 result = 0;

    // Call the procedure, and return the result
    IExecuteResult executionResult = ExecuteMethodCall(this, methodInfo, parameters);
    if (executionResult != null) result = (int)executionResult.ReturnValue;
    return result;
}

不幸的是,从 C# 5.0 开始,没有办法满足您的要求。该属性不允许每个函数有多个副本,因此您所能做的就是分解重用的代码并将其分解一点。它可能会进一步减少以删除参数对象,因为它只是从loadId无论如何构建的。

于 2015-04-29T15:48:04.430 回答
2

有什么方法可以编写一个通用方法,其中要映射到的函数名被传入?

如果您指的是通用、“可重复使用”或“样板”:是的:

private Int32 MyBoilerplateImpl(string IdArgument, string argumentName, MethodInfo method)
{
    // Validate parameter
    if (String.IsNullOrEmpty(IdArgument)) throw new ArgumentNullException(argumentName);

    // Initialise the result and the procedure parameters
    Int32 result = 0;
    object[] parameters = { IdArgument};

    // Call the procedure, and return the result
    IExecuteResult executionResult = ExecuteMethodCall(this, method, parameters);
    if (executionResult != null) 
        result = (int)executionResult.ReturnValue;
    return result;
}

并像这样调用它:

[Function(Name = "import.usp_MyData_ProcessImportAppend", IsComposable = false)]
public Int32 ProcessGradingImport(string loadId) 
{
    MyBoilerplateImpl(loadId, "loadId", (MethodInfo)(MethodBase.GetCurrentMethod());
}  
于 2015-04-29T15:48:27.530 回答