亚音速3 ActiveRecord生成的代码带有警告

亚音速3 ActiveRecord生成的代码带有警告,activerecord,subsonic,subsonic3,Activerecord,Subsonic,Subsonic3,在将亚音速3与ActiveRecord T4模板一起使用时,生成的代码显示了许多关于CLS合规性、未使用项以及缺少GetHashCode()实现的警告 为了避免它们,我做了以下修改: // Structs.tt [CLSCompliant(false)] // added public class <#=tbl.CleanName#>Table: DatabaseTable { ... // ActiveReco

在将亚音速3与ActiveRecord T4模板一起使用时,生成的代码显示了许多关于CLS合规性、未使用项以及缺少GetHashCode()实现的警告

为了避免它们,我做了以下修改:

// Structs.tt
[CLSCompliant(false)]                                    // added
public class <#=tbl.CleanName#>Table: DatabaseTable
{ ...

// ActiveRecord.tt
[CLSCompliant(false)]                                    // added
public partial class <#=tbl.ClassName#>: IActiveRecord
{
    #region Built-in testing
    #pragma warning disable 0169                         // added
    static IList<<#=tbl.ClassName#>> TestItems;
    #pragma warning restore 0169                         // added
    ...

    public override Int32 GetHashCode()                  // added
    {
      return this.KeyValue().GetHashCode();
    }

    ...
//Structs.tt
[CLSCompliant(false)]//已添加
公共类表:数据库表
{ ...
//ActiveRecord.tt
[CLSCompliant(false)]//已添加
公共部分类:IActiveRecord
{
#区域内建测试
#pragma警告禁用0169//已添加
静态IList试验;
#pragma warning restore 0169//已添加
...
公共重写Int32 GetHashCode()//已添加
{
返回此.KeyValue().GetHashCode();
}
...

是否有更好的方法消除警告?或者更好的GetHashCode()实现?

目前,消除警告的唯一方法是更新t4模板并向Rob提交错误/修复。或者等到其他人这样做

至于GetHashCode实现,我认为您不会找到通过模板实现这一点的好方法。哈希代码的生成非常依赖于对象包含的状态。而且,名字后面有很多字母的人会花很长时间、很难想出快速且返回结果的哈希代码算法在一个可能生成一个拥有数百万种不同状态排列的类的模板中完成这项工作是一项艰巨的任务

Rob所能做的最好的事情可能是提供一个默认实现,调用分部方法,检查结果并在找到结果时返回。下面是一个示例:

public partial class Foo
{
    public override int GetHashCode()
    {
        int? result = null;
        TryGetHashCode(ref result);
        if (result.HasValue)
            return result.Value;
        return new Random().Next();
    }

    partial void TryGetHashCode(ref int? result);
}

public partial class Foo
{
    partial void TryGetHashCode(ref int? result)
    {
        result = 5;
    }
}

如果您在编译时没有实现TryGetHashCode,编译器将完全忽略对TryGetHashCode的调用,您将从结果的声明转到检查它是否有值(它永远不会有值),因此将返回哈希代码的默认实现。

我希望在我们讨论时能快速解决此问题我使用的版本确实会为主键为单个int的表生成GetHashCode

由于我们的简单表使用文本作为主键,这并不是现成的

<#      if(tbl.PK.SysType=="int"){#>

        public override int GetHashCode() {
            return this.<#=tbl.PK.CleanName #>;
        }
<#      }#>
<#      else{#>
        public override int GetHashCode() {
            throw new NotImplementedException();
        }
<#      }#>

公共覆盖int GetHashCode(){
把这个还给我。;
}
公共覆盖int GetHashCode(){
抛出新的NotImplementedException();
}
这样会为所有表生成GetHashCode并停止警告,但如果调用,将抛出异常(我们没有这样做)


我们使用它是为了测试应用程序,而不是网站或类似的东西,这种方法可能在许多情况下都无效。

+1感谢您提供的代码示例,我以前从未尝试过以这种方式使用分部方法。+1我有一个只使用int/bigint主键的较旧应用程序,这个很好的解决方案可以很好地用于此应用程序。