我有一个简单的Lightswitch - 基于Silverlight的Web客户端。 Client.csproj和Server.csproj说LightSwitchVersion
是v3.0
。它运行在
我有2个分机,两个都被选中:
我有一个MySQL表
CREATE TABLE `images` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`legend` varchar(200) NOT NULL,
`preview` blob,
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
在为表创建屏幕之前,我在数据源中将preview
字段声明为 Image 类型。但正在运行的应用程序用这个
使用Lightswitch 2.0一切正常。但是因为我已经升级到v3.0,这是破坏一切的唯一问题: - (
答案 0 :(得分:0)
我自己并没有遇到过这种情况,但兴趣被激怒了。 :)
看起来OData层正在使用blob列的内容来确保数据并发性,并且URI太长了。在本机SQL Server表中,您只需添加一个Rowversion列,并且将为了并发目的而选择 - Lightswitch Intrinsic数据库实际上会自动为您执行此操作。我的理解是MySQL没有等效的Rowversion类型。
解决方法是在MySQL表上创建另一个列,每次更新时都会增加一个MySQL触发器,使其成为事实上的并发字段。更新数据源,然后编辑.lsml文件以向该列添加<UseForConcurrency />
属性。
答案 1 :(得分:0)
这是让我的方法来运行完整野兽:
在MySQL表中为并发检查添加一列:
(我决定使用uuid()
。这是每次更改内容时获取唯一值的最简单方法!)
-- The column itself.
ALTER TABLE images ADD COLUMN rowversion BINARY(16);
-- Setup for all existing rows.
UPDATE images SET rowversion = UNHEX(REPLACE(UUID(),'-',''));
-- Now make it NOT NULL.
ALTER TABLE images MODIFY COLUMN rowversion BINARY(16) NOT NULL;
-- An insert trigger to get a default value for future rows.
CREATE TRIGGER images_before_insert
BEFORE INSERT ON images
FOR EACH ROW
SET NEW.rowversion = UNHEX(REPLACE(UUID(),'-',''));
<UseForConcurrency />
(而不是更多)添加到rowversion条目中(如Phil所说)。现在它可能看起来像 <EntityProperty
Name="rowversion"
PropertyType=":Guid">
<EntityProperty.Attributes>
<UseForConcurrency />
<Required />
<NotSearchable />
</EntityProperty.Attributes>
</EntityProperty>
但是停下来,不幸的是,并非全部!这个邪恶的Lightswitch在保存后不会重新获取rowversion值。因此BEFORE UPDATE ON images
触发器永远不会满足我们的需求。相信我,你最终会进入数据冲突&#34;地狱每次更新!!!您必须在客户端更改rowversion:
public partial class ImageScreen
{
partial void ImageScreen_Saving(ref bool handled)
{
var changes = DataWorkspace.testData.Details.GetChanges();
foreach (var image in changes
.ModifiedEntities
.OfType<image>())
{
image.rowversion = Guid.NewGuid();
}
}
}
现在,客户发现了他自己的最新版本。如果另一个客户修改了相同的数据集,那么&#34;数据冲突&#34;将被正确地宣布。