繁体   English   中英

Linq和Guid的匿名类型

[英]Anonymous Type with Linq and Guid

我有一个简单的表:

ID |

当我这样做:

var sequence = from c in valuesVault.GetTable()
               select new {RandomIDX = Guid.NewGuid(), c.ID, c.Value};

投影中的每个元素都具有相同guid的值...我如何编写这个,以便为投影中的每个元素获得不同的随机guid值?

编辑

澄清这个问题。 GetTable()方法只是调用它:

        return this.context.GetTable<T>();

其中this.contenxt是类型为T的DataContext。

itteration完成,因为它总是完成,没有什么花哨的:

     foreach (var c in seq) 
     {
          Trace.WriteLine(c.RandomIDX + " " + c.Value);
     }

输出:

bf59c94e-119c-4eaf-a0d5-3bb91699b04d What is/was your mother's maiden name?
bf59c94e-119c-4eaf-a0d5-3bb91699b04d What was the last name of one of your high school English teachers?
bf59c94e-119c-4eaf-a0d5-3bb91699b04d In elementary school, what was your best friend's first and last name?

编辑2使用linq2Sql提供程序框。 我在它周围构建了一些泛型包装器,但它们不会改变代码中的IQuaryable或IEnumerable函数的方式。

valuesVault.GetTable()下面是什么?

您可能有一个Linq提供程序,如Linq 2 SQL。

这意味着valuesVault.GetTable()的类型为IQueryable ,这反过来意味着整个查询成为一个表达式

表达式是已定义但尚未执行的查询

当迭代sequence ,使用Linq提供程序执行查询,Linq提供程序和它必须执行的步骤之一是执行此表达式: Guid.NewGuid() 大多数Linq提供程序无法将该表达式传递给基础源(SQL Server不知道如何处理它),因此它会执行一次,执行结果将返回结果的其余部分。

您可以做的是通过调用.ToList().ToArray()方法强制valuesVault.GetTable()表达式成为集合 这将执行表达式并返回表示内存中集合的IEnumerable

在对IEnumerable执行查询时,执行不会传递给Linq提供程序,而是由.NET运行时执行。

在您的情况下,这意味着可以正确执行表达式Guid.NewGuid()

尝试这个:

var sequence = from c in valuesVault.GetTable().ToArray()
               select new {RandomIDX = Guid.NewGuid(), c.ID, c.Value};

注意那里的.ToArray() 这将使语句从IQueryable变为IEnumerable ,这将改变其行为。

我认为当它被翻译成SQL时会发生这种情况(即:它是数据库正在执行它)。 由于您的示例中没有WHERE子句,您可以这样做:

var sequence = from c in valuesVault.GetTable().ToList()
               select new { RandomID = Guid.NewGuid(), c.ID, c.Value };

这迫使Guid.NewGuid()在客户端执行。 但是,如果你的表增长并且你开始添加过滤子句,那就太难看了。 您可以使用第二个LINQ查询来解决它,该查询使用新GUID投影第二个结果集:

var sequence = from c in valuesVault.GetTable()
               where c.Value > 10
               select new { c.ID, c.Value };

var finalSequence = from s in sequence.ToList()
                    select new { RandomID = Guid.NewGuid(), s.ID, s.Value };

似乎为我工作。

List<int> a = new List<int> {10, 11, 12, 13};

            var v = a.Select(i => new {ID = Guid.NewGuid(), I = i});
            foreach (var item in v)
            {
                Console.WriteLine(item);
            }

产量

{ ID = b760f0c8-8dcc-458e-a924-4401ce02e04c, I = 10 }
{ ID = 2d4a0b17-54d3-4d69-8a5c-d2387e50f054, I = 11 }
{ ID = 906e1dc7-6de4-4f8d-b1cd-c129142a277a, I = 12 }
{ ID = 6a67ef6b-a7fe-4650-a8d7-4d2d3b77e761, I = 13 }

我无法使用简单的LINQ查询重现此行为。 样品:

List<int> y = new List<int> { 0, 1, 2, 3, 4, 5 };

var result = y.Select(x => new { Guid = Guid.NewGuid(), Id = x }).ToList();

我想象你是否尝试将你的Table值转换为Linq中的List,然后执行你的选择,你会得到不同的Guids。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM