【问题标题】:Will LINQ-to-SQL break if I modify underlying tables?如果我修改基础表,LINQ-to-SQL 会中断吗?
【发布时间】:2012-08-16 08:41:24
【问题描述】:

我们假设删除底层表 LINQ-to-SQL 将导致抛出异常。

我们假设删除预期的列也会导致其中断 - 它将无法插入或更新该列。但这个假设正确吗?如果我们从不尝试插入或更新该列怎么办 - 它会高兴地SELECT 该列的数据类型的默认值吗?

我们可以对破坏 LINQ-to-SQL 的基础表进行哪些更改?我们可以进行哪些更改使其忽略?它是否在运行时验证数据库架构,如果是,何时验证?

如果删除主键或外键等约束呢?我们可以在不破坏 LINQ-to-SQL 的情况下添加、删除或更改它们吗?


我知道一些我可以对基础表做的事情,我也知道一些我不能做的事情。我正在考虑的具体情况是我是否可以在不破坏 dbml 的情况下将nullable 列添加到表中。我不记得了,所以我想在这里记录一下。

【问题讨论】:

    标签: .net sql-server linq linq-to-sql


    【解决方案1】:

    在 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 但将其数据类型更改为完全不同的数据类型,例如日期时间,这甚至会起作用:

    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 会为所有字段生成正确的插入语句,这 不起作用 : ('Implicit data不允许类型转换')

    table.InsertOnSubmit(new table() { id = 2 };
    table.SubmitChanges();
    

    总而言之,只要直接在数据库上运行 SQL 语句 LINQ-To-SQL 保持有效,并且接收到的数据不与您的 DBML 相矛盾,它就不会破坏您的代码。

    【讨论】:

      【解决方案2】:

      我认为,如果您使用的是 LINQ TO SQL,并且您只修改了数据库端的表而不更新 LINQ TO SQL 模型,那么我相信您会没事的,因为模型对象没有改变并且结构是仍然相同,但如果您决定更新 LINQ TO SQL 或选择数据库上不存在的实体,它很可能会引发内部异常。当然,最正确的方法是不断保持 LINQ TO SQL 模型和数据库相同,这样可以避免很多未来的问题。如果您向 dbml 添加了一个可空列但您没有在项目中使用它,只要您不将其从 Linq 更新到 sql 就应该没问题,因为如果您这样做,您必须将其包含在您的模型中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多