首先是EF代码 - 检测给定类型的一对多关系属性

时间:2016-08-09 08:14:01

标签: c# entity-framework ef-code-first code-first

我们知道我们不需要使用Data Annotations配置一对多关系,这是一种按惯例配置的一对多关系。

在以下示例中,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)
{
    // ...
}

1 个答案:

答案 0 :(得分:1)

最简单的形式(不考虑任何自定义属性或自定义映射)。你可以这样做:

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

您可以对此进行扩展以检查属性上标记的属性,但我会将其保留给您,因为它超出了您的问题范围。