我们假设删除基础表LINQ-to-SQL将导致抛出异常。
我们假设删除预期的列也会导致它中断 - 它将无法插入或更新该列。 但这个假设是否正确? 如果我们从不尝试插入或更新该列,该怎么办 - 它会愉快地SELECT该列的数据类型的默认值吗?
我们可以对将破坏LINQ-to-SQL的基础表做出哪些更改? 我们可以做出哪些改变会忽略它? 它是否在运行时验证数据库模式,如果是,何时?
如何删除主键或外键等约束? 我们可以添加它们,删除它们,还是在不破坏LINQ-to-SQL的情况下更改它们?
我知道我可以对基础表做的一些事情,我知道一些我不能做的事情。 我正在考虑的具体情况是我是否可以在不破坏dbml的情况下向表中添加nullable为nullable列。 我不记得所以我想在这里记录它。
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.
最满意答案
在LINQ-to-SQL生成select语句并从服务器接收响应之前,不会引发异常。 即使服务器响应意外的事情(例如,字段上的不同数据类型),在您在代码中主动使用该字段之前,它可能不会导致异常。
所以,是的,你可以毫无问题地添加列,因为生成的查询不会引用它,因为它们对于DBML是未知的。 Linq-To-SQL永远不会发送SELECT * FROM TABLE ,而是发送SELECT [ID], [COL1], [COL2] FROM TABLE也不会在运行时使用SQL Server验证数据库模式。 因此,某个[COL3]是否存在不会对结果产生影响。
只是为了进一步实验 - 这当然不是明智的做法 - 让我们尝试删除和修改属于DBML的列,看看哪些有用。
如果删除[Col2],则会生成“无效列名”错误,因为服务器将尝试检索每行的所有字段,包括[col2]:
var q = from row in table select row; int id = q.First().id;但是,如果您计划在开发期间定期进行更改,则仅检索所需的字段将防止此类错误发生。 因为我们不是指[Col2],所以这有效:
var q = from row in table select new { row.id, row.Col1 }; int id = q.First().id;有点令人惊讶的是,如果你离开Col2但将其数据类型更改为完全不同的东西,比如datetime,这甚至会起作用:
var q = from row in table select new { row.id, row.Col1, row.Col2 }; int id = q.First().id;只有在积极使用该字段时才会起作用:(我得到“Nullable对象必须有值。”)
var q = from row in table select row; var col2 = q.First().Col2;只要新的未知列可以为空,您甚至可以插入行。 假设您创建了一个新的Col4,这仍然有效!
table.InsertOnSubmit(new table() { id = 1, col1 = 'A' }; table.SubmitChanges();但是,如果更改列的数据类型,请务必小心,即使您只是传递空值,也无法插入行。 如果Col1是DBML中的字符串,但您在数据库中将其更改为datetime,因为Linq-To-SQL为所有字段生成正确的insert语句,这不起作用 :('不允许隐式数据类型转换')
table.InsertOnSubmit(new table() { id = 2 }; table.SubmitChanges();总之,只要SQL语句LINQ-To-SQL在您的数据库上直接运行它们仍然有效,并且收到的数据与您的DBML不矛盾,它就不会破坏您的代码。
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 send SELECT [ID], [COL1], [COL2] FROM TABLE nor 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]:
var q = from row in table select row; int id = q.First().id;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:
var q = from row in table select new { row.id, row.Col1 }; int id = q.First().id;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:
var q = from row in table select new { row.id, row.Col1, row.Col2 }; int id = q.First().id;It's only when actively using the field that it's not gonna work: (I get "Nullable object must have a value.")
var q = from row in table select row; var col2 = q.First().Col2;You can even insert rows as long as your new unknown columns are nullable. Say you created a new Col4, this still works!
table.InsertOnSubmit(new table() { id = 1, col1 = 'A' }; table.SubmitChanges();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')
table.InsertOnSubmit(new table() { id = 2 }; table.SubmitChanges();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.
如果修改基础表,LINQ-to-SQL是否会中断?(Will LINQ-to-SQL break if I modify underlying tables?)我们假设删除基础表LINQ-to-SQL将导致抛出异常。
我们假设删除预期的列也会导致它中断 - 它将无法插入或更新该列。 但这个假设是否正确? 如果我们从不尝试插入或更新该列,该怎么办 - 它会愉快地SELECT该列的数据类型的默认值吗?
我们可以对将破坏LINQ-to-SQL的基础表做出哪些更改? 我们可以做出哪些改变会忽略它? 它是否在运行时验证数据库模式,如果是,何时?
如何删除主键或外键等约束? 我们可以添加它们,删除它们,还是在不破坏LINQ-to-SQL的情况下更改它们?
我知道我可以对基础表做的一些事情,我知道一些我不能做的事情。 我正在考虑的具体情况是我是否可以在不破坏dbml的情况下向表中添加nullable为nullable列。 我不记得所以我想在这里记录它。
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.
最满意答案
在LINQ-to-SQL生成select语句并从服务器接收响应之前,不会引发异常。 即使服务器响应意外的事情(例如,字段上的不同数据类型),在您在代码中主动使用该字段之前,它可能不会导致异常。
所以,是的,你可以毫无问题地添加列,因为生成的查询不会引用它,因为它们对于DBML是未知的。 Linq-To-SQL永远不会发送SELECT * FROM TABLE ,而是发送SELECT [ID], [COL1], [COL2] FROM TABLE也不会在运行时使用SQL Server验证数据库模式。 因此,某个[COL3]是否存在不会对结果产生影响。
只是为了进一步实验 - 这当然不是明智的做法 - 让我们尝试删除和修改属于DBML的列,看看哪些有用。
如果删除[Col2],则会生成“无效列名”错误,因为服务器将尝试检索每行的所有字段,包括[col2]:
var q = from row in table select row; int id = q.First().id;但是,如果您计划在开发期间定期进行更改,则仅检索所需的字段将防止此类错误发生。 因为我们不是指[Col2],所以这有效:
var q = from row in table select new { row.id, row.Col1 }; int id = q.First().id;有点令人惊讶的是,如果你离开Col2但将其数据类型更改为完全不同的东西,比如datetime,这甚至会起作用:
var q = from row in table select new { row.id, row.Col1, row.Col2 }; int id = q.First().id;只有在积极使用该字段时才会起作用:(我得到“Nullable对象必须有值。”)
var q = from row in table select row; var col2 = q.First().Col2;只要新的未知列可以为空,您甚至可以插入行。 假设您创建了一个新的Col4,这仍然有效!
table.InsertOnSubmit(new table() { id = 1, col1 = 'A' }; table.SubmitChanges();但是,如果更改列的数据类型,请务必小心,即使您只是传递空值,也无法插入行。 如果Col1是DBML中的字符串,但您在数据库中将其更改为datetime,因为Linq-To-SQL为所有字段生成正确的insert语句,这不起作用 :('不允许隐式数据类型转换')
table.InsertOnSubmit(new table() { id = 2 }; table.SubmitChanges();总之,只要SQL语句LINQ-To-SQL在您的数据库上直接运行它们仍然有效,并且收到的数据与您的DBML不矛盾,它就不会破坏您的代码。
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 send SELECT [ID], [COL1], [COL2] FROM TABLE nor 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]:
var q = from row in table select row; int id = q.First().id;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:
var q = from row in table select new { row.id, row.Col1 }; int id = q.First().id;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:
var q = from row in table select new { row.id, row.Col1, row.Col2 }; int id = q.First().id;It's only when actively using the field that it's not gonna work: (I get "Nullable object must have a value.")
var q = from row in table select row; var col2 = q.First().Col2;You can even insert rows as long as your new unknown columns are nullable. Say you created a new Col4, this still works!
table.InsertOnSubmit(new table() { id = 1, col1 = 'A' }; table.SubmitChanges();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')
table.InsertOnSubmit(new table() { id = 2 }; table.SubmitChanges();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.
发布评论