We assume that removing the underlying tables LINQ-to-SQL will cause to throw an exception.
We’d assume that removing an expected column would also cause it to break – it won’t be able to insert or update that column. But is that assumption correct? What if we never try to insert or update that column – will it happily SELECT the default value for that column’s datatype?
What changes can we make to the underlying tables that will break LINQ-to-SQL? What changes can we make that it will ignore? Does it validate the database schema at run time, and if so when?
What about removing constraints like primary or foreign keys? Can we add them, remove them, or change them without breaking LINQ-to-SQL?
I know some of the things I can do to the underlying tables, and I know some things I can’t do. The specific case I’m thinking about is whether I can add a nullable column to a table without breaking the dbml. I don’t remember so I wanted to document it here.
Exceptions won’t be raised before LINQ-to-SQL generates a select statement and receives a response from the server. And even if the server responds something unexpected (say, a different datatype on a field), it may not cause exceptions until you actively use that field in your code.
So yes, you can add columns without problems since the generated queries will not refer to it as they’re unknown to your DBML. Linq-To-SQL never sends
SELECT * FROM TABLE, rather it will sendSELECT [ID], [COL1], [COL2] FROM TABLEnor does it validates the database schema with SQL Server at run-time. So Whether a certain [COL3] exists or not won’t make a difference in the result.Just to experiment a little further – it’s certainly not advisable practice -, let’s try deleting and modifying columns that are part of your DBML and see what works or not.
If you delete [Col2], this will generate an “invalid column name” error since the server will attempt to retrieve all fields for each row, including [col2]:
However, if you plan to make changes regularly during development, retrieving only the fields that you require will prevent such errors from happening. Because we’re not referring to [Col2], this works:
And a little surprisingly, if you leave Col2 but change it’s datatype to something competely different, say datetime, this is even going to work:
It’s only when actively using the field that it’s not gonna work: (I get “Nullable object must have a value.”)
You can even insert rows as long as your new unknown columns are nullable. Say you created a new Col4, this still works!
However, be careful if you change the datatype of a column, you won’t be able to insert rows even if you are just passing a null value. If Col1 is a string in your DBML but you changed it to datetime in your database, because Linq-To-SQL generate a proper insert statement for all fields, this doesn’t work : (‘Implicit data type conversion not allowed’)
In summary, as long as the SQL statements LINQ-To-SQL remain valid if you would run them directly on your database, and the data received does not contradict your DBML, it won’t break your code.