【问题标题】:Linq returning a IEnumerable<Dictionary<string,string>>Linq 返回一个 IEnumerable<Dictionary<string,string>>
【发布时间】:2010-08-01 05:07:18
【问题描述】:

我需要返回一个动态创建的字典的 IEnumerable。

伪代码:

var x = from u in Users

select new dictionary<string, string>{
    Add("Name",u.Name),
    Add("LastName",u.LastName)
}

我一直在尝试很多方法来获取上面的伪代码示例,但没有成功...

非常感谢您的帮助。

【问题讨论】:

  • 你能描述一下你在做什么吗? IEnumerable&lt;Dictionary&lt;string,string&gt;&gt; 似乎有点奇怪,特别是当您必须对所有元素进行硬编码时。

标签: c# linq dictionary ienumerable


【解决方案1】:
var x = from u in Users
        select new Dictionary<string, string> {
            { "Name", u.Name },
            { "LastName", u.LastName }
        };

【讨论】:

  • 这东西没用。抛出此异常 Unrecognized expression node: ListInit 我尝试在 Dictionary 之后添加和删除 () 并且没有成功...任何想法...
  • @Tony, @mquander, Try from u in Users.AsEnumerable() as Users 可能是 IQueryable,它正在尝试在 SQL 脚本中转换整个 LINQ 语句。
【解决方案2】:

您收到“无法识别的表达式节点”错误是因为 LINQ to SQL 未能将与字典相关的代码转换为 SQL。您可以使用AsEnumerable() 使编译器改为使用 LINQ to Objects:

var x = from u in Users.AsEnumerable()
        select new Dictionary<string, string> {
            { "Name", u.Name },
            { "LastName", u.LastName }
        };

【讨论】:

    【解决方案3】:

    这是对字典的不良使用 - 您只是将其用作属性包,并创建与用户一样多的字典。
    更好地使用该语言是使用这些属性创建您自己的 User 类并使用它:

    public class User
    {
        public string Name { get; set; }
        public string LastName { get; set; }
    }
    

    还有查询:

    var users = Users.Select(u => new User
                {
                    Name = u.Name,
                    LastName = u.LastName
                });
    

    如果你只使用你的方法的集合,另一个选择是创建一个匿名类:

    var users = Users.Select(u => new { Name = u.Name, LastName = u.LastName });
    

    【讨论】:

    • 我完全理解这是一个非常糟糕的使用它,但我无法为我的情况提供更好的解决方案。这是整个场景......我正在创建一系列电子邮件模板。我想使用正则表达式动态替换一些文本 ex: "Dear [[Name]]" -> Replace([[Name]],Dictionary[Name]... 问题是我有多个实体可以从中收集数据. 伪代码仅使用实体用户,但我可能有使用用户、用户信用、用户地址的情况......所以我只想返回我的电子邮件模板中需要的那些字段。匿名类会迫使我使用反射.. .
    • 我最近做了类似的事情,并且有一个更复杂的解决方案。如果您在同一个模板上需要不同的实体怎么办? "Hello [[Name]], You've ordered [[ItemsCount]] items at $[[ItemsPrice]]. Please see &lt;a href='[[TermsURL]]'&gt;Terms of Use&lt;/a&gt;"。我有一个带有UserOrder 等的OrderContext 类,它可以用适当的字符串替换标记。这可能比将每个实体都变成字典要好。
    • 我考虑过创建一个类 EmailData ,其中包含尽可能多的道具。事情是我有 29 个模板,并且所有模板都使用了许多实体的组合。然后我不得不创建 29 个不同的 linq 来获取数据并填充 EmailData 对象。然后我必须做两件事。硬编码替换 Replace("Hello [[Name]]","[[Name]]",EmailData.Name) 或使用正则表达式获取 [[ ]] 之间的所有值并遍历该集合并使用反射调用EmailData 中的属性 EmailData.GetType().GetProperty("Name").GetValue.ToString... 所以,字典似乎更容易。
    • 这东西没用。抛出此异常 Unrecognized expression node: ListInit 我尝试在 Dictionary 之后添加和删除 () 并且没有成功...任何想法...
    【解决方案4】:

    转换方式:

    public Dictionary<string, string> ToPropertyDictionary(User theUser)
    {
      Dictionary<string, string> result = new Dictionary<string, string>();
      result.Add("Name", theUser.Name);
      result.Add("LastName", theUser.Name);
      return result;
    }
    

    调用者:

    IEnumerable<Dictionary<string, string>> x =
      from u in Users.AsEnumerable()  //ensure local execution by using AsEnumerable
      select ToPropertyDictionary(u);
    

    【讨论】:

    • 这里的另一种选择是为所有实体提供一个通用接口,并拥有User.Select(u =&gt; u.ToPropertyDictionary())
    • 这东西没用。抛出此异常 Unrecognized expression node: ListInit 我尝试在 Dictionary 之后添加和删除 () 并且没有成功...任何想法...
    • 用户...是本地收藏吗?
    • 没有。 Users 是一个 System.Data.Linq.Table (LINQtoSQL)...我一直在读一点,看来 linq 并不关心 Collection 初始化程序。从数据库中检索数据后,我可以采用旧的无聊方式并进行 foreach,但是来吧......我们在 2010 年,我认为我们不必为看起来如此简单的事情退后五年...... ..我会及时通知你。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多