上下文: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
单个用户可能在多个领域(也称为服务器)上拥有多个toons,但是每个领域必须将一个toon标记为每个用户的主要(仅适用于至少有一个香椿的领域)。
假设我有两个卡通(在一个领域):
Foo(标记为主要)
和
酒吧(不是主要的)
我想改变我的主要内容,为此我做了类似的事情: Foo.IsMain = false Bar.IsMain = true
我正在使用Linq-to-SQL。
问题:当我有一个或多个主要卡通时,如何在不进入状态的情况下进行所述转换。
注意:我有一个物化视图(由IsMain = 1过滤),它定义了一个复合键(OwnerId,RealmId),因此当我执行main-toon过渡时,我从该物化视图中获得“唯一键冲突”异常。
我已经尝试使用事务,但我仍然在'db.SubmitChanges()'上获得异常。
选项2:我怀疑我在数据库设计中存在缺陷(这个漏洞的名称是什么?)。我应该创建映射表吗?
OwnerId, RealmId -> ToonId
答案 0 :(得分:1)
问题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表中删除你的IsMain。
在此之后,您的表将是Users(Existing Stuff,MainToonId),Realms(Existing Stuff),Toons(ToonId,RealmId,OwnerId,ToonName)
第2步
正如您所建议的,您可以将Realm / Owner / Toon链接移动到其自己的表(甚至ToonOwner和ToonRealm表)。链接信息与
如果您确实选择了一个比赛表,那么新表将会有3个值组合的PK(如果您是天生的键控器),否则标准PK和3个值上的UNIQUE(如果您不是自然的话)键控器)。你应该在ToonId上有一个独特的,因为每个Toon可能只属于一个领域或所有者。