【问题标题】:Unhandled exception in linq querylinq 查询中未处理的异常
【发布时间】:2013-05-27 12:24:52
【问题描述】:

描述:进程因未处理的异常而终止。 异常信息:System.InvalidOperationException 堆栈:在 System.Data.Linq.Table1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].CheckReadOnly()
at System.Data.Linq.Table
1[[System._Canon, mscorlib, 版本=4.0.0.0,文化=中性, PublicKeyToken=b77a5c561934e089]].DeleteOnSubmit(System._Canon) 在 ReportSender.EmailReportApp.Execute() 在 System.Threading.ThreadHelper.ThreadStart_Context(System.Object) 在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback,System.Object,布尔值)在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback,System.Object)在 System.Threading.ThreadHelper.ThreadStart()

尝试删除以下查询中的记录时出现上述错误: 这个错误到底是什么意思,我该如何解决?

private void Execute()
{
    try
    {
        // Check for a new record
        DataClasses1DataContext dc = new DataClasses1DataContext();

        foreach (var item in dc.reportsSent1s)
        {
            string matchedCaseNumber = item.CaseNumberKey;

            (new MyReportRenderer()).RenderTest(matchedCaseNumber);

            dc.reportsSent1s.DeleteOnSubmit(item);
            dc.SubmitChanges();
        }   
    }
    catch (ThreadAbortException ex)
    {
        _log.WriteEntry(ex.StackTrace.ToString());
    }
}

其余代码如下:

public class MyReportRenderer
{
    private rs2005.ReportingService2005 rs;
    private rs2005Execution.ReportExecutionService rsExec;

    public void RenderTest(String matchedCaseNumber)
    {
        string HistoryID = null;
        string deviceInfo = null;
        string encoding = String.Empty;
        string mimeType = String.Empty;
        string extension = String.Empty;
        rs2005Execution.Warning[] warnings = null;
        string[] streamIDs = null;

        rs = new rs2005.ReportingService2005();
        rsExec = new rs2005Execution.ReportExecutionService();
        rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
        rsExec.Credentials = System.Net.CredentialCache.DefaultCredentials;
        rs.Url = "http://***.**.***.**/ReportServer_DEVELOPMENT/ReportService2005.asmx";
        rsExec.Url = "http://***.**.***.**/ReportServer_DEVELOPMENT/ReportExecution2005.asmx";

        try
        {
            // Load the selected report.
            rsExec.LoadReport("/LawDept/LawDeptTIC", HistoryID);

            // Set the parameters for the report needed.

            rs2005Execution.ParameterValue[] parameters = new rs2005Execution.ParameterValue[1];
            parameters[0] = new rs2005Execution.ParameterValue();
            parameters[0].Name = "CaseNumberKey";
            parameters[0].Value = matchedCaseNumber;

            rsExec.SetExecutionParameters(parameters, "en-us");

            // get pdf of report 
            Byte[] results = rsExec.Render("PDF", deviceInfo,
            out extension, out encoding,
            out mimeType, out warnings, out streamIDs);

            //pass paramaters for email
            DataClasses1DataContext db = new DataClasses1DataContext();

            var matchedBRT = (from c in db.GetTable<vw_ProductClientInfo>()
                              where c.CaseNumberKey == matchedCaseNumber
                              select c.BRTNumber).SingleOrDefault();

            var matchedAdd = (from c in db.GetTable<vw_ProductClientInfo>()
                              where c.CaseNumberKey == matchedCaseNumber
                              select c.Premises).SingleOrDefault();

            //send email with attachment
            MailMessage message = new MailMessage("Rts@acmets.com", "gge.grer@gmail.com", "Report for BRT # " + matchedAdd, "Attached if the Tax Information Certificate for the aboved captioned BRT Number");
            MailAddress copy = new MailAddress("cts@gmail.com");
            message.CC.Add(copy);
            SmtpClient emailClient = new SmtpClient("***.**.***.**");
            message.Attachments.Add(new Attachment(new MemoryStream(results), String.Format("{0}" + matchedBRT + ".pdf", "BRT")));
            emailClient.Send(message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

【问题讨论】:

  • 这可能是因为您试图从枚举中提交删除更改?您是否尝试过将提交移出循环?
  • @George Johnston:这是一个很好的理论。在表上使用活动枚举器可能会在上下文中激活只读锁,这可以解释对 CheckReadOnly 的调用失败。
  • @GeorgeJohnston 我也检查了这个理论,并将删除功能放在 emailClient.Send(message); 之后的末尾。并且仍然得到完全相同的错误。有没有更好的地方可以删除?问题是这个表是活动的,否则我会像使用非服务版本一样杀死整个事情。

标签: c# linq


【解决方案1】:

看起来 LINQ to SQL 正在检查表是否为只读表,并且正在识别表是只读的并因此抛出(您不能从只读表中删除)。因此,您需要调查为什么 LINQ to SQL 认为该表是只读的。你的桌子上有主键吗?我知道没有一个是 LINQ to SQL 认为一个表是只读的(LINQ to SQL 需要它的identity map)的常见原因。如果这不起作用,George Johnstonsuggestion 尝试将调用移至循环外的SubmitChanges 是一个好方法;在表上获取枚举器可能会在上下文中激活只读锁,这就是 CheckReadOnly 在调用提交时失败的原因。

【讨论】:

  • 它确实有一个主键,但是当我导入表时,我显然没有将它设置为一个。我继续并在数据上下文中设置为 PK,但出现了相同的错误。
  • @korrowan:试试 George 的建议。这是一个很好的理论;在表上使用枚举器可能会激活只读锁,这就是 CheckReadOnly 失败的原因。
  • 我认为你的模型还是有问题。当您修改数据库时,您是否更新了模型和类?您可以在运行时使用 (from c in dc.Mapping.GetTable(typeof(reportsSent1)).RowType.DataMembers select new { c.DbType, c.Name, c.IsPrimaryKey } ); 之类的方式检查您的模型
  • 刚刚发生了一件非常奇怪的事情。我卸载了该应用程序并重新安装了一个没有 DeleteOnSubmit 的版本,并得到了同样的错误,即使在代码中无处可见 DeleteOnSubmit。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多