我们假设删除基础表LINQ-to-SQL将导致抛出异常。
我们假设删除预期的列也会导致它中断 - 它将无法插入或更新该列。但这个假设是否正确?如果我们从不尝试插入或更新该列,该怎么办?它会愉快地SELECT
该列的数据类型的默认值吗?
我们可以对将破坏LINQ-to-SQL的基础表做出哪些更改?我们可以忽略哪些变化?它是否在运行时验证数据库模式,如果是,则何时?
如何删除主键或外键等约束?我们可以添加它们,删除它们,还是在不破坏LINQ-to-SQL的情况下更改它们?
我知道我可以对基础表做些什么,而且我知道一些我不能做的事情。我正在考虑的具体情况是我是否可以在不破坏dbml的情况下向表中添加nullable
列。我不记得所以我想在这里记录下来。
答案 0 :(得分:7)
在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为所有字段生成正确的插入语句,此不起作用 :('隐式数据类型转换不允许')
table.InsertOnSubmit(new table() { id = 2 };
table.SubmitChanges();
总之,只要SQL语句LINQ-To-SQL在您的数据库上直接运行它们仍然有效,并且收到的数据与您的DBML不矛盾,它就不会破坏您的代码。
答案 1 :(得分:0)
我认为如果您正在使用LINQ TO SQL并且您只修改了数据库端的表而没有更新LINQ TO SQL模型,那么我相信您没问题,因为模型对象没有被更改而且结构是仍然相同但是如果你决定更新LINQ TO SQL或在数据库中选择一个不存在的实体,它很可能会给你一个内部异常。尽管如此,最合适的方法是不断保持LINQ TO SQL模型和数据库是一样的,这样你就可以避免很多未来的问题。如果你向dbml添加一个nulable列,但是你没有在你的项目中使用它,只要你没有从Linq更新到sql,它应该没问题,因为如果你这样做,你必须将它包含在你的模型中