Linq to SQL Referential Integrity without database

本文关键字:without database Integrity Referential to SQL Linq | 更新日期: 2023-09-27 18:37:08

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

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

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

知道是否可以强制引用完整性吗?还是在数据库上添加关系是唯一的方法?

Linq to SQL Referential Integrity without database

您可以重写 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交谈以进行所需的更改?您可以(我想您也可以)添加一个表,但不能添加外键,因此数据库可能包含无效数据?

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

或者这绝对是一个黑客:

  • 为自己编写数据库架构脚本
  • 在您的计算机上或您想要的任何位置重新创建数据库
  • 添加新表,并向数据库添加外键
  • 从本地修改的数据库生成 linq 架构
  • 将连接字符串更改为实际字符串

而且非常脆弱:如果原始数据库有任何变化,您必须在"虚拟"数据库中更改它......

所以,还是要试着和你的老板、DBA 或谁做出这个决定,因为你无法阻止引用表中其他人的删除。