【问题标题】:EF Code first - Detect one-to-many relationships property for given typeEF Code first - 检测给定类型的一对多关系属性
【发布时间】:2016-08-09 08:14:00
【问题描述】:

我们知道我们不需要使用 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)
{
    // ...
}

【问题讨论】:

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


    【解决方案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
    

    您可以扩展它以检查属性上标记的属性,但我将把它留给您,因为它超出了您的问题范围。

    【讨论】:

    • 按照约定其他类型不能有该类型的属性,其他类型可以只有id属性。
    • @codeDom 如果第一次检查失败,您可以按照相同的逻辑检查名称为ClassName + Id 的属性是否存在于两种类型中。
    • 是的,这是一个好方法,但是第一次检查是不必要的,你可以删除他。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多