代码之家  ›  专栏  ›  技术社区  ›  THX-1138

同时换行

  •  2
  • THX-1138  · 技术社区  · 14 年前

    上下文:ASP.NET MVC 2.0,LINQ to SQL,.NET 3.5,IIS7,MS SQL 2008

    我在一个游戏迷网站工作。

    我有一张桌子如下:

    ToonId int (primary key)
    RealmId (FK into Realms table)
    OwnerId int (FK into Users table)
    ToonName nvarchar(50)
    IsMain bit
    

    也就是说,一个用户可以在多个领域(也就是服务器)上拥有多个卡通,但每个领域每个用户只能有一个卡通标记为“主”(仅适用于至少有一个卡通的领域)。

    假设我有两个玩具(在一个领域上): foo(标记为主)
    和 酒吧(非主)

    我想改变我的主要任务,为此我做了如下的事情: foo.ismain=错误 bar.ismain=真

    我正在使用Linq to SQL。

    问题: 当我有一个或零个以上的主玩具时,我如何才能在不进入状态的情况下进行上述转换?

    注意:我有一个物化视图(按ismain=1过滤),它定义了一个复合键(ownerid,realmid),例如,当我进行主toon转换时,我从物化视图中得到“唯一的键冲突”异常。

    尝试使用事务,但在“db.submitChanges()”上仍有异常。

    选项2: 我怀疑我在数据库设计上有缺陷(这个缺陷的名称是什么?)。是否应创建映射表?

    OwnerId, RealmId -> ToonId
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Community CDub    8 年前

    问题1

    您需要使用事务。

     DBDataContext db = new DBDataContext();
     using (TransactionScope ts = new TransactionScope())
     {
         try
         {
             Toon toon1 = db.Toons.First(p => p.ToonId == 4);
             Toon toon2 = db.Toons.First(p => p.ToonId == 5);
             toon1.IsMain = false;
             toon2.IsMain = true;
             db.SubmitChanges();
             ts.Complete();
         }
         catch (Exception e)
         {
            Console.WriteLine(e.Message);
         }
    }
    

    问题2

    你需要多考虑一下你的设计。

    步骤1

    它是一个有主toon的玩家,所以我会在你的用户表上放置一个maintoonid,并从你的toon表中删除你的is main。

    在此之后,您的表将是用户(现有资料、maintoonid)、realms(现有资料)、toons(toonid、realmid、ownerid、toonname)

    步骤2

    正如您所建议的,您可能可以将realm/owner/toon链接移动到它自己的表(甚至是toonoowner和toon realm表)。链接信息是 相关的 对图恩来说,但这并不是作为图恩的一部分。这个“缺陷”的解决方案是标准化,需要它的数据库被描述为“需要标准化”。然而,这一步是 完全地 在这种情况下是可选的,可能会过度正常化以满足您的需求。

    如果使用一个匹配表,新表将组合3个值的pk(如果您是自然的keyer),否则将是标准的pk和3个值上的唯一值(如果您不是自然的keyer)。你也应该有一个唯一的关于toonid,因为每个to on可能只属于一个领域或所有者。