sqlmetal中的不同[DataMember]行为比dbml designer

时间:2011-03-10 08:47:43

标签: visual-studio linq-to-sql sqlmetal

我使用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属性作为数据协定的一部分?

1 个答案:

答案 0 :(得分:0)

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

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

首先,当客户端设置ModelID而不是Model引用时,我在反序列化方面遇到了问题。如果先前已设置Model引用,则ModelID setter的SqlMetal生成代码将引发异常。这由DataMember属性的Order属性处理,这可确保在Model之前对ModelID进行反序列化。

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