没有数据库的Linq到SQL参照完整性

时间:2012-06-12 20:16:48

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

我正在编写一个使用现有数据库的应用程序,该数据库有一些表我根本无法修改,但我仍然可以添加新表。 所以,假设我有一个旧表,Cities,我可以阅读,创建,更新和删除但我无法修改架构。 然后我添加一个新表,Clients,它有一个外键给Cities,但是我不能在数据库服务器上添加关系(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

是否有可能强制引用完整性?或者在DB上添加关系是唯一的方法吗?

1 个答案:

答案 0 :(得分:1)

您可以覆盖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交谈以进行必要的更改?你可以(我猜你也可以)添加一个表,但不能添加外键,所以数据库可能包含无效数据?

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

或者这绝对是一个黑客攻击:

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

非常脆弱:如果原始数据库中有任何变化,你必须在你的“虚拟”数据库中更改它......

所以,请尝试与您的老板,DBA或做出此决定的人进行推理,因为您无法阻止被引用表格中的其他人删除。