上下文连接中的“try block中的合同部分”错误

时间:2015-01-07 16:23:12

标签: c# .net entity-framework code-contracts

我已经写了这个片段及其合同:

[Pure]
public string getLevelName()
{
    using (var c = new myContext())
    {
        Contract.Ensures(Contract.Result<string>() == c.Level.FirstOrDefault(i => i.levelId == this.levelId).name);
        return c.Level.FirstOrDefault(i => i.levelId == this.levelId).name;
    }

}

但我收到合同的错误:

  

try块中的合同部分。

如何为这种方法合同避免此错误?

3 个答案:

答案 0 :(得分:4)

尝试调用另一种方法,

public string getLevelName()
{
    using (var c = new myContext())
    {
       return getLevelNameFrom(c);
    }

}

public string getLevelNameFrom(MyContext c)
{
        Contract.Ensures(Contract.Result<string>() == c.Level.FirstOrDefault(i => i.levelId == this.levelId).name);
        return c.Level.FirstOrDefault(i => i.levelId == this.levelId).name;
}

答案 1 :(得分:1)

您必须在方法的开头放置所有Contract.Ensures次调用。 using语句是try finally块的简写(编译器为你推断这个)。

您的代码:

using (var c = new myContext())
{
    Contract.Ensures(Contract.Result<string>() == c.Level.FirstOrDefault(i => i.levelId == this.levelId).name);
    return c.Level.FirstOrDefault(i => i.levelId == this.levelId).name;
}

变成:

var c = new myContext();
try{
    Contract.Ensures(Contract.Result<string>() == c.Level.FirstOrDefault(i => i.levelId == this.levelId).name);
}
finally
{
    if (c != null)
        ((IDisposable)c).Dispose();
}

所以基本上你将一个Contract.Ensures调用放入一个try块(就像错误告诉你的那样)。特别参见这篇msdn文章http://msdn.microsoft.com/en-us/library/dd412865.aspx

  

此方法调用必须位于方法或属性的开头,在任何其他代码之前。

答案 2 :(得分:1)

文档says

  

此方法调用必须位于方法或属性的开头,   在任何其他代码之前。

在你的样本中

using (var c = new myContext())

将被编译为

try 
{
  c = new myContext();
  Contract.Ensures ...
}
finally
{
   c.Dispose();
}

要避免这种情况,请使用其他私有方法并传递上下文