在 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 object must have a value。”)
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 为所有字段生成正确的插入语句,这不起作用:('不允许隐式数据类型转换')
table.InsertOnSubmit(new table() { id = 2 };
table.SubmitChanges();
总之,只要直接在数据库上运行 SQL 语句 LINQ-To-SQL 仍然有效,并且接收到的数据不与您的 DBML 相矛盾,它就不会破坏您的代码。