EF代码第一 - 检测一到多的关系属性给定类型 [英] EF Code first - Detect one-to-many relationships property for given type

查看:225
本文介绍了EF代码第一 - 检测一到多的关系属性给定类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们知道,我们不需要使用数据注释为一对多的关系配置,一对多的关系按照惯例构造



在以下例如的ICollection<的Student GT;学生是一个关系属性。



<预类=郎-C#prettyprint-覆盖> 公共类学生
{
公益助学(){}

公众诠释StudentId {搞定;组; }
公共字符串StudentName {搞定;组; }

公共虚标标准{搞定;组; }
}

公共类标准
{
公共标准()
{
学生=新的List<学生>();
}
公众诠释StandardId {搞定;组; }
公共字符串描述{搞定;组; }

公共虚拟的ICollection<的Student GT;学生{搞定;组; }
}



所以我的问题是,我怎么能检测到的关系propertys对于一个给定类型?
我的目标是测试的财产一样,价值和它多少个项目包含



东西:



<预类=郎-C#prettyprint-覆盖> 静态无效测试(对象givenInstanse)
{
的foreach(在TryGetOneToManyRelationshipsPropertys的PropertyInfo p(typeof运算(givenInstanse),DC) )
{
VAR VAL =(ICollection的)p.GetValue(givenInstanse);
Console.WriteLine(val.Count);
}
}

静态的IEnumerable<&的PropertyInfo GT; TryGetOneToManyRelationshipsPropertys(T型,DC的DbContext)
{
// ...
}


< DIV CLASS =h2_lin>解决方案

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

 的IEnumerable<&的PropertyInfo GT; GetOneToManyRelationships< T>()
{从typeof运算(T).GetProperties()
p
VAR collectionProps =其中p.PropertyType.IsGenericType
和;&安培; p.PropertyType.GetGenericTypeDefinition()
== typeof运算(ICollection的<>)
的选择P;

的foreach(在collectionProps VAR道具)
{
变种类型= prop.PropertyType.GetGenericArguments()(第)。

//如果这个检查其它类型有这种类型的一个属性。
布尔HasOneProperty = type.GetProperties()任何(X => x.PropertyType == typeof运算(T));

如果
{
串pkName = typeof运算(T).Name点+ID(HasOneProperty!);

HasOneProperty = type.GetProperties()任何(X => x.Name.Equals(pkName,
StringComparison.OrdinalIgnoreCase));
}

如果(HasOneProperty)
{
收益率的回报道具;
}
}
}



用法:



  VAR oneToManyProps = GetOneToManyRelationships<标GT;(); 

的foreach(在oneToManyProps VAR道具)
{
Console.WriteLine(prop.Name);
}



输出:

 学生

您可以扩展此检查属性标签上性质,但我会留给你,因为它是你的问题的范围。


We know that we do not need to configure for one-to-many relationships using Data Annotations, one-to-many relationship configured by convention.

In following example ICollection<Student> Students is an relationship property

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; }
}

So my question is, how can I detect a relationship propertys for a given type? My goal is to test the value of the property and how many items it contains

Something like that:

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)
{
    // ...
}

解决方案

In its simplest form (Not taking into considerations any custom attributes or custom Mappings). You can do this:

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;
        }
    }
}

Usage:

var oneToManyProps = GetOneToManyRelationships<Standard>();

foreach(var prop in oneToManyProps)
{
    Console.WriteLine(prop.Name);
}

Output:

Students

You can extend this to check for Attributes tagged on properties, but i'll leave that to you as it is outside the scope of your question.

这篇关于EF代码第一 - 检测一到多的关系属性给定类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆