Home

LINQPad should warn if a user function will override a DataContext method

I wrote out some scripts that was intended to query a database, update some rows, and save them back. When I attempted to run them, it seemed like the changes wouldn't go through. After some long debugging sessions and major alterations to my script, I eventually found out that the name of some methods was causing the conflicts.

Let's say one of the tables I was updating was called: MyTable. I happened to create a function that had the signature:
void UpdateMyTable(MyTable)
It wasn't public/protected, there was no override, there was no warnings so I expected no issues. I eventually ended up renaming that method to FixMyTable(MyTable) and everything worked out.

I think that LINQPad should be able to detect this situation and at least warn about it. There might be legitimate cases where we'd want to actually override it, but I would have expected the override modifier would be required.

Comments

  • What kind of data context are you using? I've tried the following - both with the default LINQ-to-SQL context and with a custom Entity Framework 6 context:
    void Main()
    {
        UpdateCustomer (Customers.First());
    }
    
    void UpdateCustomer (Customer c)
    {
        "I am here".Dump();
    }
    In both cases, it works as expected. I've also tried defining a method as follows:
    void SubmitChanges()
    {	
    }
    This results in an immediate green underline, and when you run the query a warning symbol in the editor margin - CS0108 SubmitChanges hides inherited member 'DataContext.SubmitChanges'.
  • I have been using the default LINQ-to-SQL driver. I'll have to double check my connection settings when I get to the office next week, but I'm pretty sure I didn't pluralize the table names and I wonder if that would make a difference.

    I probably could have checked the stack trace as I was debugging too, it might have revealed more. But in my attempts to determine what was wrong, I moved the calls to SubmitChanges() in and out of methods. When I put it in the update method and stepped through, it immediately jumped to the top of my update method.

    Something like:
    void UpdateMyTable(MyTable myTable)
    {
    if (/* myTable object needs to be updated */)
    {
    /* update the myTable object */
    SubmitChanges();
    }
    }
    I don't know if it would be appropriate for me to post the exact code, but I'll come up with something representative of how it was set up.
  • Here's a simple test case I set up using v5.26.01 (any).

    image
    --setup
    use tempdb
    create table TestName(id integer identity(1, 1) primary key, name varchar(20) not null)
    insert into TestName values ('foo'), ('bar'), ('biz'), ('baz')
    void Main()
    {
    var query =
    from t in TestName
    where t.id == 1
    select t;
    foreach (var t in query)
    UpdateTestName(t);
    SubmitChanges();
    query.Dump();
    }

    // Define other methods and classes here
    void UpdateTestName(TestName testName)
    {
    if (!testName.name.StartsWith("(updated)"))
    {
    testName.Dump("updating");
    testName.name = $"(updated)({testName.name})";
    }
    else
    {
    "no update".Dump();
    }
    }
    and the output:

    image
    note the "no update" in the output

    In the end, the table doesn't get updated. I could rerun the query multiple times and the table will still be untouched. There are no further errors.
  • This doesn't require an override because there is no method to override, but Linq2Sql is just looking for a method with this name and uses it if it exists.

    You can see more if you look at the reference source (see here or here)


    I'm not sure sure what the advantage of 'duck-typing' is in this case, but one big disadvantage is that you do not get compiler warnings if you happen to use one of those special names for your own methods and if you are not aware of these special names (and I admit I wasn't until I read this thread), then you can end up with unexpected behaviour.
Sign In or Register to comment.