EF 代码优先 - 检测给定类型的一对多关系 属性
EF Code first - Detect one-to-many relationships property for given type
我们知道我们不需要使用数据注释配置一对多关系,一对多关系按约定配置。
在下面的例子中 ICollection<Student> Students
是一个关系 属性
public class Student
{
public Student() { }
public int StudentId { get; set; }
public string StudentName { get; set; }
public virtual Standard Standard { get; set; }
}
public class Standard
{
public Standard()
{
Students = new List<Student>();
}
public int StandardId { get; set; }
public string Description { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
所以我的问题是,如何检测给定类型的关系 属性?
我的目标是测试 属性 的值以及它包含多少项
类似的东西:
static void Test(object givenInstanse)
{
foreach (PropertyInfo p in TryGetOneToManyRelationshipsPropertys(typeof(givenInstanse), dc))
{
var val = (ICollection)p.GetValue(givenInstanse);
Console.WriteLine(val.Count);
}
}
static IEnumerable<PropertyInfo> TryGetOneToManyRelationshipsPropertys(Type t, DbContext dc)
{
// ...
}
最简单的形式(不考虑任何自定义属性或自定义映射)。你可以这样做:
IEnumerable<PropertyInfo> GetOneToManyRelationships<T>()
{
var collectionProps = from p in typeof(T).GetProperties()
where p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition()
== typeof(ICollection<>)
select p;
foreach (var prop in collectionProps)
{
var type = prop.PropertyType.GetGenericArguments().First();
// This checks if the other type has a One Property of this Type.
bool HasOneProperty = type.GetProperties().Any(x => x.PropertyType == typeof(T));
if(!HasOneProperty)
{
string pkName = typeof(T).Name + "Id";
HasOneProperty = type.GetProperties().Any(x => x.Name.Equals(pkName,
StringComparison.OrdinalIgnoreCase));
}
if (HasOneProperty)
{
yield return prop;
}
}
}
用法:
var oneToManyProps = GetOneToManyRelationships<Standard>();
foreach(var prop in oneToManyProps)
{
Console.WriteLine(prop.Name);
}
输出:
Students
您可以扩展它以检查属性上标记的属性,但我会把它留给您,因为它超出了您的问题范围。
我们知道我们不需要使用数据注释配置一对多关系,一对多关系按约定配置。
在下面的例子中 ICollection<Student> Students
是一个关系 属性
public class Student
{
public Student() { }
public int StudentId { get; set; }
public string StudentName { get; set; }
public virtual Standard Standard { get; set; }
}
public class Standard
{
public Standard()
{
Students = new List<Student>();
}
public int StandardId { get; set; }
public string Description { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
所以我的问题是,如何检测给定类型的关系 属性? 我的目标是测试 属性 的值以及它包含多少项
类似的东西:
static void Test(object givenInstanse)
{
foreach (PropertyInfo p in TryGetOneToManyRelationshipsPropertys(typeof(givenInstanse), dc))
{
var val = (ICollection)p.GetValue(givenInstanse);
Console.WriteLine(val.Count);
}
}
static IEnumerable<PropertyInfo> TryGetOneToManyRelationshipsPropertys(Type t, DbContext dc)
{
// ...
}
最简单的形式(不考虑任何自定义属性或自定义映射)。你可以这样做:
IEnumerable<PropertyInfo> GetOneToManyRelationships<T>()
{
var collectionProps = from p in typeof(T).GetProperties()
where p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition()
== typeof(ICollection<>)
select p;
foreach (var prop in collectionProps)
{
var type = prop.PropertyType.GetGenericArguments().First();
// This checks if the other type has a One Property of this Type.
bool HasOneProperty = type.GetProperties().Any(x => x.PropertyType == typeof(T));
if(!HasOneProperty)
{
string pkName = typeof(T).Name + "Id";
HasOneProperty = type.GetProperties().Any(x => x.Name.Equals(pkName,
StringComparison.OrdinalIgnoreCase));
}
if (HasOneProperty)
{
yield return prop;
}
}
}
用法:
var oneToManyProps = GetOneToManyRelationships<Standard>();
foreach(var prop in oneToManyProps)
{
Console.WriteLine(prop.Name);
}
输出:
Students
您可以扩展它以检查属性上标记的属性,但我会把它留给您,因为它超出了您的问题范围。