C# 使用内置Linq to SQL驱动程序在LinqPad中运行实体框架核心查询的更简单方法?

C# 使用内置Linq to SQL驱动程序在LinqPad中运行实体框架核心查询的更简单方法?,c#,frameworks,entity,core,linqpad,C#,Frameworks,Entity,Core,Linqpad,注意:这是一个老问题。使用LinqPad 5时,您有我在下面描述的限制,因为它不是用.NET Core编写的。但是现在您可以使用更新的,它完全支持实体框架核心,包括多个数据库系统的驱动程序 我想分析实体框架核心查询,我将其从现有代码复制到LinqPad中 UserQuery this_context; void Main() { this_context = this; var validationResult = ( from ProjectInfo pi

注意:这是一个老问题。使用LinqPad 5时,您有我在下面描述的限制,因为它不是用.NET Core编写的。但是现在您可以使用更新的,它完全支持实体框架核心,包括多个数据库系统的驱动程序


我想分析实体框架核心查询,我将其从现有代码复制到LinqPad中

UserQuery this_context;
void Main()
{
    this_context = this;
    var validationResult = (

        from ProjectInfo pi in this_context.GetAll<ProjectInfo>()
        join GeneralInformation gi in this_context.GetAll<GeneralInformation>() 
                                   on pi.Id equals gi.Id into gpi
        from gps in gpi.DefaultIfEmpty()

        select new { ... }).ToList();
}
UserQuery这个上下文;
void Main()
{
这个上下文=这个;
var validationResult=(
来自此上下文中的ProjectInfo pi.GetAll()
在此上下文中连接GeneralInformation gi.GetAll()
关于pi.Id等于gi.Id到gpi
从gpi.DefaultIfEmpty()中的gps
选择新的{…}).ToList();
}
我知道,Linqpad不支持.NET Core,因此我必须对其进行一些调整-为此,我创建了一个扩展方法,如下所示:

public static class Ext
{
    public static  IEnumerable GetAll<T>(this UserQuery uq)
    where T: new()
    {
        return GetAll(uq, new T());
    }

    private static  IEnumerable GetAll<T>(this UserQuery uq, T a)
    {
        switch (a)
        {
            case ProjectInfo v:
                return uq.ProjectInfo.Select(s => s);
            case GeneralInformation v:
                return uq.GeneralInformation.Select(s => s);

            // ... many more cases like the above 

            default: // unknown type
                throw new TypeAccessException($"Unsupported type {a.GetType().FullName}");
        }
    }
    
}
公共静态类Ext
{
公共静态IEnumerable GetAll(此UserQuery uq)
其中T:new()
{
返回GetAll(uq,newt());
}
私有静态IEnumerable GetAll(此UserQuery uq,TA)
{
开关(a)
{
案例五:
返回uq.ProjectInfo.Select(s=>s);
案例概述信息五:
返回uq.GeneralInformation.Select(s=>s);
//…还有更多类似上述的案例
默认值://未知类型
抛出新的TypeAccessException($“不支持的类型{a.GetType().FullName}”);
}
}
}
重载的
GetAll
函数是获取类型所必需的-它只是创建一个空的新对象并将其传入,以便switch语句可以正确地扣除正确的类型并返回正确的查询

这很好,但是要在switch语句中输入每一种类型需要花费大量的精力

所以我的问题是:


如何以更智能的方式实现这一点,即不必指定每个实体类型?

LINQPad的
UserQuery
对象似乎有一种方法正是您想要的:

public static class Ext {
    public static IEnumerable GetAll<T>(this UserQuery uq) =>uq.GetTable(typeof(T));
}

很好,这正是我想要的。非常感谢!但是,类型安全版本由于未知原因阻止了InvalidOperationException。可能在
GetTable
之后需要
.AsQueryable()
?当我使用与MS SQL的连接进行测试时,没有发现错误。我添加了另一个可能工作得更好的类型安全版本。两个类型化版本都抛出了
invalidoOperationException:cannottranslateexpression'表(ProjectInfo).Cast().GroupJoin(表(GeneralInformation).Cast(),pi=>pi.Id…
,而非类型化版本(答案中的第一个)works Fine我终于找到了一种方法让它使用类型化结果:
public static IEnumerable GetAll(this UserQuery uq)=>(IEnumerable)uq.GetTable(typeof(T))原因是接口类<代码> iQueEnaby和 Advesty/Cuth>不是100%与LINQ兼容。@ Matt,我不认为是正确的。<代码> iQueEdaby<代码>是LINQ(to SQL/EF)的基础。。如果您强制转换为
IEnumerable
,我会担心您将整个表拉入内存,而不是执行SQL查询,而是LINQ到对象,这可能会有细微的不同。
public static IQueryable<T> GetAll<T>(this UserQuery uq) => (IQueryable<T>)uq.GetTable(typeof(T));
public static ITable<T> GetAll<T>(this UserQuery uq) where T : class => (ITable<T>)uq.GetTable(typeof(T));