Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF Core从重数为0或1的模型中获取实体的导航属性_C#_Navigation Properties_Ef Core 2.2 - Fatal编程技术网

C# EF Core从重数为0或1的模型中获取实体的导航属性

C# EF Core从重数为0或1的模型中获取实体的导航属性,c#,navigation-properties,ef-core-2.2,C#,Navigation Properties,Ef Core 2.2,我正在创建一个泛型类,用集成测试所需的实体为数据库种子。 我可以创建单个实体,但当一个实体依赖于另一个实体时,我必须手动指示我的类首先创建父实体,然后继续。 我正在尝试自动进行此检测,从模型定义中获取具有多重性0或1的导航属性列表引用导航属性,一旦完成,我的类将递归地调用自身以创建父实体。首先,循环依赖项超出了此处的范围 我曾经在EF for.net Framework中这样做,但EF Core已经改变了很多。 我在EF Core中缺少的是RelationshipMultiplicity,我在官

我正在创建一个泛型类,用集成测试所需的实体为数据库种子。 我可以创建单个实体,但当一个实体依赖于另一个实体时,我必须手动指示我的类首先创建父实体,然后继续。 我正在尝试自动进行此检测,从模型定义中获取具有多重性0或1的导航属性列表引用导航属性,一旦完成,我的类将递归地调用自身以创建父实体。首先,循环依赖项超出了此处的范围

我曾经在EF for.net Framework中这样做,但EF Core已经改变了很多。 我在EF Core中缺少的是RelationshipMultiplicity,我在官方文档中找不到任何关于Multiplicity的参考,甚至困难的解决方案是检查导航属性是否是一个集合,我希望有更多的控制权并保持简单

到目前为止,我正在使用以下方法探索模型定义:

var modelData = _context.Model.GetEntityTypes()
    .Select(t => new
    {
        t.ClrType.Name,
        DerivedNavigationProperties = t.FindDerivedNavigations(t.ClrType.Name),
        DefiningNavigationProperties = t.FindDefiningNavigation(),
        DeclaredForeignKeys = t.GetDeclaredForeignKeys(),
        DeclaredNavigations = t.GetDeclaredNavigations(),
        DerivedNavigations = t.GetDerivedNavigations(),
        DerivedNavigationsInclusive = t.GetDerivedNavigationsInclusive(),
        Navigations = t.GetNavigations() // This returns all Navigation Properties (INavigation)
    });

在检查了GitHub中的源代码之后,我可以非常自信地说,EF核心中不存在多重性

我创建了一个与.net Framework 3.5+使用的枚举类似的枚举,请参见:

然后是一个扩展方法,它允许使用枚举作为筛选器获取所有导航属性。 我使用的关键内容是:

调用的初始化的扩展方法 所有物 该方法允许按关系类型获取所有导航属性

public static class ModelExtensions
{
    /// <summary>
    /// Extension method used to get from the entity all navigation properties by multiplicity
    /// </summary>
    /// <typeparam name="T">Entity from where the navigation properties are taken</typeparam>
    /// <param name="model">Context Model</param>
    /// <param name="multiplicity">Type of multiplicity to use</param>
    /// <returns>List of PropertyInfo of Navigation Properties</returns>
    public static IEnumerable<PropertyInfo> GetNavigationProperties<T>(this IModel model, RelationshipMultiplicity multiplicity)
    {
        var navigations = model.GetEntityTypes().FirstOrDefault(m => m.ClrType == typeof(T))?.GetNavigations();
        var properties = new List<PropertyInfo>();

        switch (multiplicity)
        {
            case RelationshipMultiplicity.Many | RelationshipMultiplicity.ZeroOrOne:
                return navigations?
                    .Select(nav => nav.PropertyInfo);
            case RelationshipMultiplicity.Many:
                return navigations?
                    .Where(nav => nav.IsCollection())
                    .Select(nav => nav.PropertyInfo);
            case RelationshipMultiplicity.One:
                return navigations?
                    .Where(nav => !nav.IsCollection() && nav.ForeignKey.IsRequired)
                    .Select(nav => nav.PropertyInfo);
            case RelationshipMultiplicity.ZeroOrOne:
                return navigations?
                    .Where(nav => !nav.IsCollection())
                    .Select(nav => nav.PropertyInfo);
            default:
                return null;
        }

        return properties;
    }
}
用法示例:

var oneToManyRelations = _context.Model.GetNavigationProperties<Transaction>(
    RelationshipMultiplicity.ZeroOrOne);

var manyToOneRelations = _context.Model.GetNavigationProperties<Transaction>(
    RelationshipMultiplicity.Many);

var allRelations = _context.Model.GetNavigationProperties<Transaction>(
    RelationshipMultiplicity.Many | 
    RelationshipMultiplicity.ZeroOrOne);
var oneToManyRelations = _context.Model.GetNavigationProperties<Transaction>(
    RelationshipMultiplicity.ZeroOrOne);

var manyToOneRelations = _context.Model.GetNavigationProperties<Transaction>(
    RelationshipMultiplicity.Many);

var allRelations = _context.Model.GetNavigationProperties<Transaction>(
    RelationshipMultiplicity.Many | 
    RelationshipMultiplicity.ZeroOrOne);