2

我已经使用 linq-to-sql 接管了一个应用程序,现在计划对数据库进行一些重大更改。由于不支持刷新 dbml 设计器中的模型,我尝试改用 sqlmetal。但是,我遇到了 sqlmetal 生成的代码与 dbml 设计器生成的 colde 不兼容的问题。

如果我有一个表(例如 Car),它有一个 FK 到另一个表(例如 Model),那么序列化会有所不同,它不会为关联属性生成 DataMember 属性:

// **************************
// *** Dbml designer code ***
// **************************

[ColumnAttribute(...)]
[DatamemberAttribute(...)]
public int ModelID
{
    // property get and set
}

[AssociationAttribute(...)]
[DataMemberAttribute(...)]
public Model Model
{
    // property get and set
}

// **********************
// *** Sqlmetal code ****
// **********************

[ColumnAttribute(...)]
[DatamemberAttribute(...)]
public int ModelID
{
    // property get and set
}

[AssociationAttribute(...)]
// No DataMember attribute 
public Model Model
{
    // property get and set
}

有没有办法解决这个问题,在使用 sqlmetal 时让 Model 属性成为数据合同的一部分?

4

1 回答 1

0

我最终使用了一个包装器属性:

[DataMember(Name="Model", Order=100)]
public Model ModelDataMember
{
    get
    {
        return Model;
    }
    set
    {
        if(value != null)
        {
            Model = value;
        }
    }
}

首先,当客户端设置了 ModelID 但没有设置 Model 引用时,我在反序列化方面遇到了问题。如果先前已设置模型引用,则为 ModelID 设置器生成的 SqlMetal 代码将引发异常。这由 DataMember 特性的 Order 属性处理,确保 ModelID 在 Model 之前反序列化。

它仍然不起作用,因为现在在设置 ModelID 而不是 Model 引用时反序列化时,Model 引用设置器会将 ModelID 清零。与 dbml 设计器生成的代码相比,此行为不同,只有 SqlMetal 将 ModelID 属性与 Model 属性同步。解决方案是跳过 stter if valueis null

于 2011-03-16T10:25:23.413 回答