动态设置值为C#中函数属性的参数

时间:2013-07-04 09:22:05

标签: c# asp.net sql linq-to-sql

我在使用Linq DataContext从数据库获取数据列表时遇到问题

我正在尝试关注代码

  

public class DBContextNew:DataContext       {

    public static string StoreProcedureName = "";

    [Function(Name = StoreProcedureName, IsComposable = false)]
    public ISingleResult<T> getCustomerAll()
    {

        IExecuteResult objResult =
          this.ExecuteMethodCall(this, (MethodInfo)(MethodInfo.GetCurrentMethod()));

        ISingleResult<T> objresults =
            (ISingleResult<T>)objResult.ReturnValue;
        return objresults;
    }


}

但是我的错误

  

[Function(Name = StoreProcedureName,IsComposable = false)]

     

as属性参数必须是常量表达式typeof   表达式或数组创建表达式的属性参数类型

我想在运行时将值传递给Name属性。

有可能吗?

请帮忙。

3 个答案:

答案 0 :(得分:0)

问题是:

 public static string StoreProcedureName = "";

你需要让它成为一个常数。

public const string StoreProcedureName = "";

编译器在错误消息中告诉您(它必须是常量表达式)。

答案 1 :(得分:0)

不幸的是,您无法向属性声明提供动态值(如变量的内容)。

但是,您可以在运行时更改属性的值:

public class TestAttribute : Attribute
{ public string Bar { get; set; } }

public class TestClass
{
    [Test]
    public string Foo()
    { return string.Empty; }
}

然后更改此值:

var method = typeof(TestClass).GetMethod("Foo");
var attribute = method.GetCustomAttribute(typeof(TestAttribute)) as TestAttribute;
attribute.Bar = "Hello";

请记住,您的班级的所有实例都会共享属性。

答案 2 :(得分:0)

使用城堡动态代理代替简单属性。因为使用属性执行它会强制您在运行时使用反射来更改属性参数中的某些内容。这样,就像user1908061建议会导致2个问题:

1)性能问题。在运行时调用存储过程对于应用程序的性能来说非常“重量级” 2)Multy-thread问题。让我们假设2个线程以10个刻度的间隔调用此代码

var method = typeof(TestClass).GetMethod("Foo");
var attribute = method.GetCustomAttribute(typeof(TestAttribute)) as TestAttribute;
attribute.Bar = "Hello";

Thread1会将Bar param的属性更改为“Hello”,此时Thread2将访问相同的代码,并将Bar param更改为其他值,这将导致问题。让我们在时间轴上看一下:

 0 ticks - Thread1 started to work, accessed the property of TestAttribute and made the Bar param = "Hello"
 20 ticks - Thread2 started to work, accessed the property of TestAttribute and made the Bar param = "SomeOtherValue"
 40 ticks - You are expecting that you will call function with `Bar`=="Hello", but it's getting called with the `Bar`=="SomeOtherValue"
 60 ticks - Thread2 getting called with `Bar`=="SomeOtherValue"

所以你的Thread1会得到错误的结果。

所以我建议使用CastleDynamicProxy来做你想要的。有了它,你可以在方法之前运行一些代码并替换方法的结果,也可以在方法之后运行一些代码。这种方式可以在运行时使用。

还有一项技术 - PostSharp也可以用另一种方式做同样的事情。这个将在编译时工作。