【问题标题】:C#, What's the proper syntax for calling an Expression<Func<T-in, T-out>> from within another lambda expression?C#,从另一个 lambda 表达式中调用 Expression<Func<T-in, T-out>> 的正确语法是什么?
【发布时间】:2013-10-18 06:41:31
【问题描述】:

我正在使用 Entity Framework 5,但在创建要在方法中使用的表达式时遇到问题。

我认为问题在于通常我会在 lambda 表达式中调用该表达式,例如 dbContext.Counties.Select(GetLargeCities()),但在我正在使用的代码中,我将 Counties 实体投影到名为 CountyWithCities 的视图模型中。在我通常调用表达式的地方,我有一个单例 c 并且不知道如何在那里调用表达式。

我想使用表达式完成此操作的原因是因为我希望 GetCountiesWithCities 方法访问数据库一次,而 Entity Framework 为结果中的所有对象构造一个复杂的图形。

由于某种原因,下面的代码会产生错误“当前上下文中不存在名称 'GetLargeCities'。”

    public class CountyWithCities // this is a view model
    {
        public int CountyID { get; set; }
        public string CountyName { get; set; }
        public IEnumerable<City> Cities { get; set; }
    }

    public class City // this is an entity
    {
        public int CityID { get; set; }
        public string CityName { get; set; }
        public int Population { get; set; }
    }

    public IEnumerable<CountyWithCities> GetCountiesWithCities(int StateID)
    {
        return dbContext.States
            .Where(s => s.StateID = StateID)
            .Select(s => s.Counties)
            .Select(c => new CountyWithCities
            {
                CountyID = c.CountyID,
                CountyName = c.CountyName,
                Cities = GetLargeCities(c) // How do I call the expression here?
            });
    }

    public Expression<Func<County, IEnumerable<City>>> GetLargeCities = county =>
        county.Cities.Where(city => city.Population > 50000);

谢谢!

【问题讨论】:

    标签: entity-framework-5 lambda


    【解决方案1】:

    我通常使用扩展方法来做到这一点。

    public static IQueriable<City> LargeCities(this IQueriable<County> counties){
        return counties
            .SelectMany(county=>county.Cities.Where(c=>c.Population > 50000));
    }
    

    用法:

    dbContext.Counties.LargeCities()
    
    
       public IEnumerable<CountyWithCities> GetCountiesWithCities(int StateID)
        {
            return dbContext.States
                .Where(s => s.StateID = StateID)
                .Select(s => s.Counties)
                .LargeCities()
                .GroupBy(c=>c.County)
                .Select(c => new CountyWithCities
                {
                    CountyID = g.Key.CountyID,
                    CountyName = g.Key.CountyName,
                    Cities = g.AsQueriable() // i cant remember the exact syntax here but you need the list from the group
                });
        }
    

    【讨论】:

    • 卢克,我试过你回答,但它抛出LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable`1[MyData.County] GetLargeCities()' method, and this method cannot be translated into a store expression. 也许我的问题是我试图在投影.Select(c =&gt; new CountyWithCities { }) 中使用方法inside。我还注意到,尽管将扩展方法键入为IQueryable&lt;City&gt;,但错误表明该方法正在返回IEnumerable&lt;City&gt;
    • 引用这个答案 (stackoverflow.com/a/4044751/125292) “编译的函数不能转换为 SQL,只有表达式可以。”所以我认为扩展方法在这里不起作用。我希望不是这样。
    • 您不能在 lambda 中间调用它,但您可以将它用作将立即执行的查询链的一部分。我已经包含了一种使用它的建议方式(它不在我的脑海中,所以语法 ext 可能不太正确)
    • 卢克,我正在寻找一种从 lambda 中间调用表达式的方法。另一方面,您的回答向我展示了如何跨链式方法维护 IQueryable (this IQueryable&lt;T&gt; source)。感谢您的帮助。
    • @Kuyenda 我知道在 lambda 中实际调用表达式的唯一方法是使用可重用的表达式树。 Linqkit 允许这样做,但它有点工作
    猜你喜欢
    • 1970-01-01
    • 2019-01-11
    • 2021-08-25
    • 2010-10-22
    • 1970-01-01
    • 2021-10-15
    相关资源
    最近更新 更多