0
votes

Description: The process was terminated due to an unhandled exception. Exception Info: System.InvalidOperationException Stack: at 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, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].DeleteOnSubmit(System._Canon) at ReportSender.EmailReportApp.Execute() at System.Threading.ThreadHelper.ThreadStart_Context(System.Object) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Threading.ThreadHelper.ThreadStart()

I am getting the above error when attempting to delete a record in the following query: What does this error mean exactly and how do I fix it?

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());
    }
}

The rest of the code is as follows:

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("[email protected]", "[email protected]", "Report for BRT # " + matchedAdd, "Attached if the Tax Information Certificate for the aboved captioned BRT Number");
            MailAddress copy = new MailAddress("[email protected]");
            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);
        }
    }
}
1
Could this possibly be because you are attempting to submit your delete changes from within the enumeration? Have you tried moving the submit outside of the loop? - George Johnston
@George Johnston: This is a good theory. Taking an active enumerator on the table could be activating a readonly lock within the context which could explain the failed call to CheckReadOnly. - jason
@GeorgeJohnston I checked this theory as well and put the delete function at the end just after emailClient.Send(message); and still get the EXACT same error. WOuld there be a better place to put the delete? Problem is this table is active or I would just kill the whole thing like I do with the non service version. - korrowan

1 Answers

1
votes

Looks like LINQ to SQL is checking if the table is readonly or not, and is discerning that the table is readonly and throwing as a result (you can't delete from a readonly table). So, you need to investigate why LINQ to SQL thinks the table is readonly. Do you have a primary key on the table? I know that not having one is a common cause of LINQ to SQL thinking a table is readonly (LINQ to SQL needs it for its identity map). If that doesn't work, George Johnston's suggestion to try moving the call to SubmitChanges outside of the loop is a good one; getting an enumerator on the table could be activating a readonly only lock within the context and that's why CheckReadOnly is failing on the call to submit.