【问题标题】:Entity Framework/C#: multiple includes from string array?实体框架/C#:来自字符串数组的多个包含?
【发布时间】:2013-12-18 05:26:24
【问题描述】:

如果想在某些实体框架选择上使用Include() 方法(以避免“对象已处理”异常)。 但是 Include 只接受一个字符串作为参数,这意味着只包含一个。 要进行多个包含,您必须链接包含.Include("something").Include("something").Include("something")

但我希望我的包含来自字符串数组。

所以我想写的相当于.Include(array[0]).Include(array[1]).Include(array[2])...Include(array[n])

(其中'n' = array.Length - 1)

当然我事先不知道字符串数组中会是什么。

但到目前为止我找不到正确的语法。 谢谢你的帮助

编辑:鉴于我到目前为止的建议,我想说请准确说明类型并避免空值问题并对其进行测试。到目前为止,似乎没有任何解决方案有效,我迷失在我能用这种或那种类型做什么和不能做什么。

【问题讨论】:

  • 我认为.Include("something,something2,something3") 会起作用
  • @MehmetInce 没有接受“字符串参数”的 Include 方法的重载;因此,除非您明确定义该方法,否则这是不可能的。
  • @Mehmet:我尝试了逗号分隔“Entity1.Entity1b,Entity2.Entity2b”,但我收到并错误提及“Entity1b,Entity2”
  • 永远不要盲目地链接包含。你知道他们对你的查询输出做了什么吗?输出可以根据关联的多样性呈指数增长。三个以上的包含应该是例外且经过深思熟虑的。

标签: c# arrays entity-framework include


【解决方案1】:

您可以使用params string[],这将使您的代码更加清晰:

public static IQueryable<T> Include<T>(this IDbSet<T> dbSet, params string[] includes) where T : class
{
    foreach (var include in includes)
        dbSet.Include(include);

    return dbSet;
}

那么你可以同时使用它:

.Include("NavProp1", "NavProp2", "NavProp3");

还有:

.Include(new[] { "NavProp1", "NavProp2", "NavProp3" });

【讨论】:

  • 问题:IDbSet 没有 Include(),DbSet 有。问题是我想以列表结尾+这不会以任何方式保留我需要的数据。我虽然 dbSet = dbSet.Include(include);但类型不同 + 复制/粘贴此方法并运行它会产生我无法准确解释的 stackoverflow 错误,因为字符串不是 string[] 所以它不会引起混淆,我将其重命名为 IncludeArray 以运行它。
  • IDbSet.Include()IQueryableExtensions 提供。见msdn.microsoft.com/en-us/library/gg679233(v=vs.113).aspx
【解决方案2】:
    public IEnumerable<T> GetDataWithIncludes<T>(string[] includes) where T: class, new()
    {
        DbQuery<T> dbQuery = null;
        DbSet<T> dbSet = this.Set<T>();
        foreach (string include in includes)
        {
            dbQuery = dbSet.Include(include);
        }

        return dbQuery.AsEnumerable();
    }

【讨论】:

  • 到目前为止的其他建议,这仍然没有解决我的问题。我首先认为如果 include 为空,null 值会出现问题,但显然即使 include 不为空也会出现这样的问题。
  • @TTT 你能澄清一下这个问题吗?有什么例外?
【解决方案3】:

您总是可以将它们链接在一个循环中:

var query = DataSource.Select(...).Where(...); // as IQueryable<T>
foreach(string include in includes)
{
   query = query.Include(include);
}

return query.ToList(); // materialize

【讨论】:

  • 对不起,我选择了这个作为答案,但是尝试根据 3 个回复做出自己的解决方案,我意识到 IQueryable 没有 Include() 方法。
【解决方案4】:

对于调查此问题的其他人,我通过结合 @haim770 和 @daryal 解决方案想出了一个解决方案。它根据string[] includes 参数将给定的 Context DbSet 扩展为 Queryble 并更新局部变量并继续追加

扩展类

public static class Extensions
    {
        public static IQueryable<T> IncludeMany<T>(this DbSet<T> model, params string[] includes)
            where T : class
        {
            var modelQuerable = model.AsQueryable();
            foreach (var value in includes)
            {
                modelQuerable = modelQuerable.Include(value);
            }
            return modelQuerable;
        }
}

实施

public async Task<TestModel> GetData(Guid id)
        {
            var testModel= await context.TestModel.IncludeMany(
                    "xx",
                    "yy",
                    "xx.zz"
                    ).All();
            return testModel;
        }

我希望这可以帮助人们寻找答案,即使这个问题有点老了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2013-11-26
    • 2015-08-10
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    相关资源
    最近更新 更多