c# - 没有数据库的 Linq to SQL 引用完整性

标签 c# sql-server-2008 linq-to-sql

我正在编写一个使用现有数据库的应用程序,该数据库有一些表我根本无法修改,但我仍然可以添加新表。 所以,假设我有一个旧表 Cities,我可以读取、创建、更新和删除它,但我不能修改模式。 然后我添加了一个新表 Clients,它有一个到 Cities 的外键,但我无法在数据库服务器(SQL SERVER 2008)上添加一个关系,因为它也修改了 Cities 表,添加了一个关系。 所以我想也许如果我将它们都添加到我的 linq-to-sql 上下文中,并在那里添加关系,linq-to-sql 将足够聪明地为我检查参照完整性,即使关系没有建立在数据库,它在上下文中。

我创建了一个新项目来尝试这个,我添加了两个没有关系的简单表,然后在 linq-to-sql 设计器上添加了关系,并试图在参照完整性上强制异常(exception),但看起来它不是工作。

DBContextDataContext db = new DBContextDataContext();

City l = new City();
l.name= "Buenos Aires";
db.Cities.InsertOnSubmit(l);

Client c = new Client();
c.name = "Mike";
c.City = l;
db.Clients.InsertOnSubmit(c);

db.SubmitChanges(); // This works

db.Cities.DeleteOnSubmit(l); 
db.SubmitChanges(); // This shouldn't work, but it works

知道是否可以强制参照完整性吗?或者在数据库上添加关系是唯一的方法?

最佳答案

您可以覆盖 DataContex 上的 SubmitChanges 方法,并验证所做的更改。

    public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
    {
        bool everythingIsOK = true;

        var changes = GetChangeSet();
        var inserts = changes.Inserts;
        var deletes = changes.Deletes;
        var updates = changes.Updates;

        //verify everything is valid
        //...

        //if you need to, you can get the original state of the updated objects like this:
        foreach(object x in updates) {
            var original = this.GetTable(x.GetType()).GetOriginalEntityState(x);
            //verify the change doesn't break anything
            //...
        }

        if(everythingIsOK){ base.SubmitChanges(failureMode); }
    }

但感觉很痛。您绝对确定您不能与 DBA 交谈以进行所需的更改吗?您可以(我想您也可以)添加一个表,但不能添加外键,因此数据库可能包含无效数据?

此外,如果您必须以这种方式验证更改,则意味着您必须对数据库进行更多查询以验证所有 key 等是否有效。

或者这绝对是一个 hack:

  • 为自己编写数据库模式脚本
  • 在您的机器上或任何您想要的地方重新创建数据库
  • 添加新表,并向数据库添加外键
  • 从本地修改后的数据库生成 linq 模式
  • 将连接字符串改成真实的

而且非常脆弱:如果原始数据库发生任何变化,您必须在“虚拟”数据库中进行更改...

因此,请尝试与您的老板、DBA 或做出此决定的人讲道理,因为您无法阻止其他人在引用表中进行删除。

关于c# - 没有数据库的 Linq to SQL 引用完整性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11004172/

相关文章:

c# - 从自引用数据库表填充递归数据结构

c# - 将字节数组复制到 C# 中的另一个字节数组

c# - 无法将 lambda 表达式转换为类型 'string',因为它不是委托(delegate)类型

sql - SELECT DISTINCT 非常慢

sql - 需要帮助创建 linq 选择

c# - linq to sql 查询帮助

c# - 创建线程前台 VS Thread.Join()

c# - 如何捕获特定数据的版本历史记录并突出显示从当前版本到先前版本的更改

sql-server - 如何按周顺序显示记录

sql-server - 存储过程与表值函数的 OUTPUT 子句