在Entity Framework下了解多个表结果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Entity Framework下了解多个表结果相关的知识,希望对你有一定的参考价值。

为了显示一个页面,我需要从各种表中获取大量信息,而现在,加载页面大约需要20秒,这太可怕了。

所以我想将所有内容都移到一个Store Procedure中,并以旧的DataTable方式获取所有信息。

我明白了

public WinnerPageInformation FindWinnerPageInformation(int calendarId)
{
    BackendPagesContext ctx = new BackendPagesContext(db.Connection);
    IMultipleResults results = ctx.WinnersBackendPageInformation(calendarId);

    return new WinnerPageInformation()
    {
        Challenges = results.GetResult<Challenges>(),
        Content = results.GetResult<ContentWinners>().FirstOrDefault(),
        Einfo = results.GetResult<ContentEmails>().FirstOrDefault(),
        Fields = results.GetResult<SubscriberFields>(),
        Prizes = results.GetResult<Prizes>(),
        Winners = results.GetResult<Winners>()
    };
}

和WinnersBackendPageInformation看起来像这样

public class BackendPagesContext : DataContext
{
    public BackendPagesContext(System.Data.IDbConnection connection) 
        : base(connection) { }

    [Function(Name = "dbo.sp_GetWinnersBackendPageInformation")]
    [ResultType(typeof(JK_ContentWinners))]
    [ResultType(typeof(JK_Winners))]
    [ResultType(typeof(JK_SubscriberFields))]
    [ResultType(typeof(JK_Prizes))]
    [ResultType(typeof(JK_Challenges))]
    [ResultType(typeof(JK_ContentEmails))]
    public IMultipleResults WinnersBackendPageInformation(
        [Parameter(Name = "calendarId", DbType = "Int")] int calendarId)
    {
        IExecuteResult result =
        this.ExecuteMethodCall(this,
                               ((MethodInfo)(MethodInfo.GetCurrentMethod())),
                               calendarId);
        return (IMultipleResults)(result.ReturnValue);
    }
}

public interface IMultipleResults : IFunctionResult, IDisposable
{
    IEnumerable<TElement> GetResult<TElement>();
}

但我遇到的问题是,this.ExecuteMethodCall行抛出一个错误,说结果不是MultipleTable结果。

我的商店程序看起来像

ALTER PROCEDURE sp_GetWinnersBackendPageInformation
    @calendarId numeric = 0
AS
BEGIN 
    SELECT * FROM ContentWinners WHERE calendar_id = @calendarId;
    SELECT * FROM Winners WHERE calendar_id = @calendarId;
    SELECT * FROM SubscriberFields WHERE calendar_id = @calendarId ORDER BY position;
    SELECT * FROM Prizes WHERE calendar_id = @calendarId ORDER BY prizetype_id, to_day, title;
    SELECT * FROM Challenges WHERE calendar_id = @calendarId;
    SELECT * FROM ContentEmails WHERE calendar_id = @calendarId;
END
GO

错误信息是

为函数'WinnersBackendPageInformation'声明的多个结果类型不返回IMultipleResults。

我错过了什么?

答案

你没有遗漏任何东西。

实体框架4不支持存储过程中的多个结果集。

如果您阅读here博客文章,您将从EF团队的成员那里找到此声明:

不幸的是,这次我们无法全面支持产品中的多个结果。但是,我们将方法Translate<T>添加到ObjectContext,它允许您从DataReader中实现对象。因此,如果您有一个存储过程返回多个结果,其属性直接与EF对象对齐,那么您可以从上下文(context.Connection.StoreConnection)获取底层存储连接,创建一个命令并使用它来执行存储过程和回到DataReader。然后你可以调用Translate<FirstObjectType>并找回这些对象的数量,然后是reader.NextResult()Translate<SecondObjectType>等。

所以,你可以使用一些“老派”ADO.NET,或者你可以尝试在CodePlex上的EF Extensions项目,它似乎可以为你做管道工作。

以上是关于在Entity Framework下了解多个表结果的主要内容,如果未能解决你的问题,请参考以下文章

在Entity Framework Code First中为同一个表定义多个外键

如何在dotnet core Entity Framework中对多个表的数据进行GroupBy操作?

Entity Framework 4 和查询结果的缓存

Entity Framework Many to Many Relation Mapping(Entity Framework多对多关系映射)

Entity Framework 4.1 Fluent API 中的多个类映射到同一个表

Entity Framework表拆分