我有以下课程,
用户:
public class User:Domain
{
[Sortable]
public string FirstName { get; set; }
[Sortable]
public string LastName { get; set; }
[NestedSortable]
public Profile Profile { get; set; }
}
个人资料:
public class Profile : Domain
{
[Sortable]
public string BrandName { get; set; }
[NestedSortable]
public Client Client { get; set; }
[NestedSortable]
public ProfileContact ProfileContact { get; set; }
}
客户:
public class Client : Domain
{
[Sortable]
public string Name { get; set; }
}
个人资料联系人:
public class ProfileContact : Domain
{
[Sortable]
public string Email { get; set; }
}
我正在编写一个递归函数,以获取所有用[Sortable]
装饰的属性。当我只有一个[NestedSortableProperty]
时,此方法效果很好,但当我有多个private static IEnumerable<SortTerm> GetTermsFromModel(
Type parentSortClass,
List<SortTerm> sortTerms,
string parentsName = null,
bool hasNavigation = false)
{
if (sortTerms is null)
{
sortTerms = new List<SortTerm>();
}
sortTerms.AddRange(parentSortClass.GetTypeInfo()
.DeclaredProperties
.Where(p => p.GetCustomAttributes<SortableAttribute>().Any())
.Select(p => new SortTerm
{
ParentName = parentSortClass.Name,
Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
Default = p.GetCustomAttribute<SortableAttribute>().Default,
HasNavigation = hasNavigation
}));
var complexSortProperties = parentSortClass.GetTypeInfo()
.DeclaredProperties
.Where(p => p.GetCustomAttributes<NestedSortableAttribute>().Any());
if (complexSortProperties.Any())
{
foreach (var parentProperty in complexSortProperties)
{
var parentType = parentProperty.PropertyType;
if (string.IsNullOrWhiteSpace(parentsName))
{
parentsName = parentType.Name;
}
else
{
parentsName += $".{parentType.Name}";
}
return GetTermsFromModel(parentType, sortTerms, parentsName, true);
}
}
return sortTerms;
}
时,效果不佳。
这是我的递归函数:
foreach
发生这种情况是由于 FirstName
循环内的return语句。如何重写呢?在此示例中,我需要获取LastName
,BrandName
,Name
,Email
和Email
的列表。但是我只得到除yield return
之外的前四个属性。
现在,通过删除下面我自己的答案中所发布的return语句并遵循@Dialecticus注释来使用[NestedSortable]
,可以解决上述问题。所以我点击并更新了问题。
现在我遇到了另一个问题。如果一个类具有多个User
属性,则会错误地分配父类名称。
第一次使用var declaredTerms = GetTermsFromModel(typeof(User), null);
类的parentsName
类调用此方法
示例
在第一次调用后,[Sortable]
参数将为null,并且User
类中的[NestedSortable]
属性无效。
现在,对于Profile
类中的User
parentsName
属性,Profile
将是[Sortable]
,因此{{ 1}}类将Profile
设为Name
,依此类推。
Profile.BrandName
属性如下,
预期输出:
名字,姓氏,Profile.BrandName,Profile.Client.Name,Profile.ProfileContact.Email
但实际输出:
名字,姓氏,Profile.BrandName,Profile.Client.Name,Profile.Client.ProfileContact.Email
请协助解决此问题。
谢谢
阿卜杜勒
答案 0 :(得分:0)
经过一些调试后,我在foreach
循环中删除了return语句,并修复了第一个问题。
更改自
return GetTermsFromModel(parentType, sortTerms, parentsName, true);
到
GetTermsFromModel(parentType, sortTerms, parentsName, true);
然后按照@Dialecticus注释删除,将sortTerms
作为输入参数,并删除代码中的参数,并将sortTerms.AddRange(...)
更改为yield return
。
更改自
sortTerms.AddRange(parentSortClass.GetTypeInfo()
.DeclaredProperties
.Where(p => p.GetCustomAttributes<SortableAttribute>().Any())
.Select(p => new SortTerm
{
ParentName = parentSortClass.Name,
Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
Default = p.GetCustomAttribute<SortableAttribute>().Default,
HasNavigation = hasNavigation
}));
到
foreach (var p in properties)
{
yield return new SortTerm
{
ParentName = parentSortClass.Name,
Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
Default = p.GetCustomAttribute<SortableAttribute>().Default,
HasNavigation = hasNavigation
};
}
对于复杂属性,也从更改为
GetTermsFromModel(parentType, sortTerms, parentsName, true);
到
var complexProperties = GetTermsFromModel(parentType, parentsName, true);
foreach (var complexProperty in complexProperties)
{
yield return complexProperty;
}
对于最后一个问题,我遇到了这个名称,在内部foreach
循环修复它之后,添加以下代码,
parentsName = parentsName.Replace($".{parentType.Name}", string.Empty);
这是完整的更新后的工作代码:
private static IEnumerable<SortTerm> GetTermsFromModel(
Type parentSortClass,
string parentsName = null,
bool hasNavigation = false)
{
var properties = parentSortClass.GetTypeInfo()
.DeclaredProperties
.Where(p => p.GetCustomAttributes<SortableAttribute>().Any());
foreach (var p in properties)
{
yield return new SortTerm
{
ParentName = parentSortClass.Name,
Name = hasNavigation ? $"{parentsName}.{p.Name}" : p.Name,
EntityName = p.GetCustomAttribute<SortableAttribute>().EntityProperty,
Default = p.GetCustomAttribute<SortableAttribute>().Default,
HasNavigation = hasNavigation
};
}
var complexSortProperties = parentSortClass.GetTypeInfo()
.DeclaredProperties
.Where(p => p.GetCustomAttributes<NestedSortableAttribute>().Any());
if (complexSortProperties.Any())
{
foreach (var parentProperty in complexSortProperties)
{
var parentType = parentProperty.PropertyType;
//if (string.IsNullOrWhiteSpace(parentsName))
//{
// parentsName = parentType.Name;
//}
//else
//{
// parentsName += $".{parentType.Name}";
//}
var complexProperties = GetTermsFromModel(parentType, string.IsNullOrWhiteSpace(parentsName) ? parentType.Name : $"{parentsName}.{parentType.Name}", true);
foreach (var complexProperty in complexProperties)
{
yield return complexProperty;
}
//parentsName = parentsName.Replace($".{parentType.Name}", string.Empty);
}
}
}