Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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
LINQ到SQL EntitySet中的泄漏抽象_Linq_Linq To Sql_Entity Framework - Fatal编程技术网

LINQ到SQL EntitySet中的泄漏抽象

LINQ到SQL EntitySet中的泄漏抽象,linq,linq-to-sql,entity-framework,Linq,Linq To Sql,Entity Framework,我遇到了一些dbml生成的类的问题,这些类不需要解析为高效的SQL。假设我有一个Accounts表和一个Transactions表,其中每个事务都与一个特定的帐户相关联。我将所有这些加载到dbml中,并弹出一个Account类和一个Transaction类。Account类有一个EntitySet引用,该引用指向表示该帐户上所有事务的事务集合。很公平 现在假设我只想要当前会计期间的交易记录。因此,我添加了如下方法: public IEnumerable<Transaction> Cu

我遇到了一些dbml生成的类的问题,这些类不需要解析为高效的SQL。假设我有一个Accounts表和一个Transactions表,其中每个事务都与一个特定的帐户相关联。我将所有这些加载到dbml中,并弹出一个Account类和一个Transaction类。Account类有一个EntitySet引用,该引用指向表示该帐户上所有事务的事务集合。很公平

现在假设我只想要当前会计期间的交易记录。因此,我添加了如下方法:

public IEnumerable<Transaction> CurrentTransactions
{
    get
    {
        DateTime dtStart = CurrentPeriod;
        DateTime dtEnd = NextPeriod;
        return
            from t in Transactions
            orderby t.date
            where t.date >= CurrentPeriod && t.date <= NextPeriod
            select t;
    }
}
Ie:它将整个事务集拉下来,并使用LINQ for Object进行处理。我试着去掉where子句,orderby子句,用常量替换日期,这一切仍然在客户端完成

为了进行比较,我尝试直接从数据上下文调用Transactions集合:

DateTime dtStart = account.CurrentPeriod;
DateTime dtEnd = account.NextPeriod;
IEnumerable<Transaction> trans=
                from t in MyDataContext.Transactions
                orderby t.date
                where t.date >= dtStart && t.date <= dtEnd && t.account_id==iAccountID
                select t;
DateTime dtStart=account.CurrentPeriod;
DateTime dtEnd=account.NextPeriod;
IEnumerable trans=
来自MyDataContext.Transactions中的t
订购日期

其中,t.date>=dtStart&&t.date=@p0)和([t0].[date]从使用IEnumerable全境切换到IQueryable,您的SQL将被优化为只按需拉取您需要的事务。

第一个示例中的事务类型是什么

请记住,您使用的是扩展方法。所使用的Linq扩展方法取决于接口事务实现:

  • IQueryable将是linq到sql或linq到实体或
  • IEnumerable将为对象提供linq
编辑:

这是EntitySet类型的指纹:

public sealed class EntitySet<TEntity> : IList, 
    ICollection, IList<TEntity>, ICollection<TEntity>, IEnumerable<TEntity>, 
    IEnumerable, IListSource
where TEntity : class
公共密封类EntitySet:IList,
ICollection,IList,ICollection,IEnumerable,
IEnumerable,IListSource
地点:班级
回答您的问题:

  • 事务未实现IQueryable,因此这是正确的行为
  • 您的account类需要能够引用Transactions表对象

  • 遗憾的是,您无法做到这一点。为LINQ to SQL实体类生成的集合属性不是
    IQueryable
    ;因此,对它们执行的任何查询都将使用LINQ to对象。这是出于设计。正如您自己正确指出的,要获得高效查询,您必须查询从
    数据中获取的
    事务aContext
    ,但属性gettor中没有

    此时,您可以选择:

    • 使其成为以
      DataContext
      为参数的方法;或
    • 使用reflection hackery检索上下文-实体本身不存储上下文,但其上的EntitySet
    s存储上下文,尽管是间接的-这自然是特定于版本的,容易被破坏,等等
    据我所知,实体框架没有这个限制,因为它的集合属性是
    ObjectQuery
    ,这是
    IQueryable
    ,它不会。他的问题是
    Transactions
    不是
    IQueryable
    ,他不能对它做任何事情(它是一个
    EntitySet
    ,必须是一个).Yep这正是问题所在。Argh.从来不是一个简单的解决方案。:)事务是dbml生成的EntitySet属性。[Association(Name=“Account\u Transaction”,Storage=“\u Transactions”,ThisKey=“id”,OtherKey=“Account\u id”)]公共实体设置事务2)。我理解这一点,问题是,如果帐户对象通常由数据上下文/实体框架创建,那么如何获得这样的引用?我将在何处连接以向account对象传递对transactions表的引用?或者,换句话说,给定一个与特定数据上下文关联的实体对象,如何从该实体返回其数据上下文?您是在扩展Account对象的功能,对吗?是否添加参数化方法调用?IEnumerable GetCurrentTransactions(DataContext ctx)我假设Account对象定义为分部类,或者您可以创建一个扩展方法。Yes Account对象是分部类。我想将dc传递给方法是可以的,只是我使用Account对象作为强类型MVC视图的类型,而我目前没有可用的dc。考虑到这一点,我想我会重新安排它,为MVC视图使用一个新对象,直接从dc而不是通过帐户获取事务。尽管如此,我还是对dbml生成的类如此容易泄漏感到惊讶——我认为我所尝试的是一种相当标准的东西。至少从2009年到现在,Entity Framework的集合属性不是
    ObjectQuery
    类型,而是
    EntityCollection
    (但是,它有一种方法可以将它们转换为
    ObjectQuery
    )。
    SELECT [t0].[id], [t0].[account_id], [t0].[date], [t0].[description], [t0].[amount], [t0].[sign]
    FROM [dbo].[transactions] AS [t0]
    WHERE ([t0].[date] >= @p0) AND ([t0].[date] <= @p1) AND ([t0].[account_id] = @p2)
    ORDER BY [t0].[date]
    
    public sealed class EntitySet<TEntity> : IList, 
        ICollection, IList<TEntity>, ICollection<TEntity>, IEnumerable<TEntity>, 
        IEnumerable, IListSource
    where TEntity : class