Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NRefactory:如何访问属性上未解析的命名参数?_C#_Nrefactory - Fatal编程技术网

C# NRefactory:如何访问属性上未解析的命名参数?

C# NRefactory:如何访问属性上未解析的命名参数?,c#,nrefactory,C#,Nrefactory,我为一个简单问题的冗长描述提前道歉,但我想确保人们正确理解我的意图 背景 我正在编写一个工具,可以读入SqlMetal生成的文件,并创建一个类,该类包含用于简单插入、更新、删除和选择的方法,然后可以将这些方法公开给web服务。这里的主要优点是,如果表发生更改,我只需重新运行该工具,与数据库相关的代码就会自动更新,使用该工具的任何地方都会生成编译错误,从而可以轻松跟踪需要进行手动更改的位置。例如,如果我有一个包含以下字段的Customer表: 客户ID(主键、标识) 名字 姓氏 我希望能够生成

我为一个简单问题的冗长描述提前道歉,但我想确保人们正确理解我的意图

背景 我正在编写一个工具,可以读入SqlMetal生成的文件,并创建一个类,该类包含用于简单插入、更新、删除和选择的方法,然后可以将这些方法公开给web服务。这里的主要优点是,如果表发生更改,我只需重新运行该工具,与数据库相关的代码就会自动更新,使用该工具的任何地方都会生成编译错误,从而可以轻松跟踪需要进行手动更改的位置。例如,如果我有一个包含以下字段的Customer表:

  • 客户ID(主键、标识)
  • 名字
  • 姓氏
我希望能够生成插入和删除方法,如下所示:

// I only want non-database-generated fields to be parameters here.
public static Customer InsertCustomer(String firstName, String lastName)
{
...
}

// I only want the primary key fields to be parameters here.
public static int DeleteCustomer(int customerId)
{
...
}
我正在使用SqlMetal生成一个Customer类。现在我要做的是将该.cs文件读入我的新工具中,以便使用上述方法创建另一个类。然后,可以将这个新类公开给web服务,以授予对该功能的访问权,而不必公开底层数据库。我正在使用NRefactory读取SqlMetal生成的文件,到目前为止,进展顺利,但在尝试读取Customer类的属性时遇到了障碍

SqlMetal使用ColumnAttribute生成其类,以标识从数据库列派生的每个属性。ColumnAttribute将有许多参数来描述数据库列的属性。在上面的示例中,它将生成如下内容:

...
[Column(Name="customerId", Storage="_CustomerId, DbType="INT NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int CustomerId
{
...
}


[Column(Name="firstName", Storage="_FirstName", DbType="NVarChar(100) NOT NULL", CanBeNull=false)]
public String FirstName
{
...
}


[Column(Name="lastName", Storage="_LastName", DbType="NVarChar(100) NOT NULL", CanBeNull=false)]
public String LastName
{
...
}
...
问题 如您所见,SqlMetal为我提供了所需的属性,以便识别哪些列是数据库生成的,哪些列是主键的一部分。因此,当我将此文件读入NRefactory并解析类型时,我希望能够获得所有这些信息。但是,我发现虽然我可以访问ColumnAttribute,但它的所有参数都没有解析,因此无法通过NamedArguments或PositionArguments属性访问

这是我的密码:

SyntaxTree syntaxTree = ...;
foreach(AstNode tableNode in syntaxTree.Children)
{
    ResolveResult result = resolver.Resolve(tableNode);
    var properties = result.Type.GetProperties();
    foreach (IProperty p in properties)
    {
        var attributes = p.Attributes;
        bool isPrimaryKeyField = false;
        bool isDbGenerated = false;
        bool isColumn = false;
        foreach (IAttribute attr in attributes)
        {
            if (attr.AttributeType.Name == "Column")
            {
                isColumn = true;
                foreach (var arg in attr.NamedArguments) // NamedArguments contains no items.
                {
                    if (arg.Key.Name == "IsPrimaryKey")
                    {
                        isPrimaryKeyField = (bool)arg.Value.ConstantValue == true;
                    }

                    if (arg.Key.Name == "IsDbGenerated")
                    {
                        isDbGenerated = (bool)arg.Value.ConstantValue == true;
                    }
                }
            }
        }

        if (isColumn)
        {
            ... // Create a parameter as appropriate.
        }
    }
}
在我尝试循环使用IAttribute.NamedArguments之前,这一切都是有效的,因为集合不包含任何元素。然而,当我通过调试器检查'attr'的值时,我可以看到有一个名为'unresolved'的私有变量,它包含我想要的所有参数的列表,但我无法通过代码访问它


如何获取此“未解析”变量的内容?我需要对解析器做更多的操作吗?这是我第一次使用NRefactory,所以我还不太熟悉所有的细微差别。我一直很难在谷歌上找到一个深入到这个层次的例子,而我在NRefactory上看到的文档似乎没有涵盖它。任何帮助都将不胜感激。

我想出来了。在解析SyntaxTree之前,我需要将System.Data.Linq的程序集加载到IProjectContent中

...
CecilLoader loader = new CecilLoader();
Assembly[] assembliesToLoad = {
    ...
    typeof(System.Data.Linq.Mapping.ColumnAttribute).Assembly
    ...};

IUnresolvedAssembly[] projectAssemblies = new IUnresolvedAssembly[assembliesToLoad.Length];
for(int i = 0; i < assembliesToLoad.Length; i++)
{
    projectAssemblies[i] = loader.LoadAssemblyFile(assembliesToLoad[i].Location);
}

IProjectContent project = new CSharpProjectContent();
project = project.AddAssemblyReferences(projectAssemblies);
...
。。。
Ceciloader loader=新Ceciloader();
Assembly[]assembliesToLoad={
...
typeof(System.Data.Linq.Mapping.ColumnAttribute).Assembly
...};
IUnresolvedAssembly[]ProjectAssembly=新的IUnresolvedAssembly[assembliesToLoad.Length];
for(int i=0;i