【问题标题】:Include method from Entity Framework from in .NET Framework 4.5 is incompatible with .NET Standard 2.0.NET Framework 4.5 中 Entity Framework 的包含方法与 .NET Standard 2.0 不兼容
【发布时间】:2023-03-10 04:52:01
【问题描述】:

最初这个类是用 .NET 框架 4.5 编写的,我现在将它转换为 .NET Standard 2.0。但是,include 方法的行为不再相同。我收到以下错误:

“IQueryable”不包含“包含”的定义,也没有 可访问的扩展方法“包括”接受第一个参数 可以找到类型“IQueryable”(您是否缺少 using 指令或 程序集参考?)

正在使用的库:

using Microservices.LibCore.Core;
using Microservices.LibCore.Core.Base.Models;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Reflection;

public static IQueryable<T> IncludeRelated<T>(this IQueryable<T> originalQuery, int maxLevel = 2, bool includeCollections = false)
    {
        if (Config.get<bool>("EntityUtil_IncludeRelatedCollectionsAlways", false))
        {
            includeCollections = true;
        }

        var includeFunc = IncludeRelatedRecursive(typeof(T), "", 1, maxLevel, includeCollections);

        if (includeFunc != null)
        {
            return (IQueryable<T>)includeFunc(originalQuery);
        }
        else
        {
            return originalQuery;
        }
    }

private static Func<IQueryable, IQueryable> IncludeRelatedRecursive(Type type, string root, int level, int maxLevel, bool includeCollections = false)
    {
        if (level > maxLevel)
        {
            return null;
        }

        if (includeCollections)
        {
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection<>))
            {
                type = type.GetGenericArguments()[0];
            }
        }
        Func<IQueryable, IQueryable> includeFunc = null;

        foreach (var prop in type.GetProperties()

            .Where(p => Attribute.IsDefined(p, typeof(ForeignKeyAttribute)) &&
            !Attribute.IsDefined(p, typeof(JsonIgnoreAttribute))))
        {
            var includeChildPropFunc = IncludeRelatedRecursive(prop.PropertyType, root + prop.Name + ".", level + 1, maxLevel, includeCollections); //propertiesChecked

            if (includeChildPropFunc != null)
            {
                includeFunc = Compose(includeFunc, includeChildPropFunc);
            }
            else
            {
                Func<IQueryable, IQueryable> includeProp = f => f.Include(root + prop.Name);

                includeFunc = Compose(includeFunc, includeProp);
            }
        }
        return includeFunc;
    }

【问题讨论】:

  • 为什么要在查询中包含整个对象图?只需抓住您要使用的位。大量的小请求得到了需要的东西,而不是一个巨大的请求得到了所有的东西,其中大部分没有被重新使用并且会被滥用。
  • IQueryable 没有 Include() 方法,它是一个扩展方法。很难理解为什么 this answer 有用,但 Slight 的评论可能很相关。
  • @HansPassant 如果我没有使用 .NET Standard 框架,我相信这会奏效。但是我使用的是 Microsoft.EntityFrameworkCore;来自 Microsoft.EntityFrameworkCore.SqlServer.
  • @Neil 不幸的是,这是由于数据库(遗留)结构不佳和应用程序的需求造成的。

标签: c# entity-framework microservices .net-framework-version .net-standard-2.0


【解决方案1】:

包含在 Microsoft.EntityFrameworkCore 命名空间和 Microsoft.EntityFrameworkCore.dll 程序集中:

EntityFrameworkQueryableExtensions.Include Method

但在 EF Core 中,它需要 IQueryable&lt;T&gt;,而不是 IQueryable。由于您使用反射来遍历实体图(因此没有编译时实体类型 T),因此您必须使用反射来调用 Include。有点像这样:

    public static System.Linq.IQueryable Include(this System.Linq.IQueryable source, string navigationPropertyPath)
    {
        var entityType = source.GetType().GetGenericArguments().Single();

        var includeMethodGenericDefinition = typeof(Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions).GetMethods()
                                                .Where(m => m.Name == "Include")
                                                .Where(m => m.GetParameters()[1].ParameterType == typeof(string))
                                                .Single();
        var includeMethod = includeMethodGenericDefinition.MakeGenericMethod(entityType);

        return (IQueryable)includeMethod.Invoke(null, new object[] { source, navigationPropertyPath });

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多