Linq"无法将表达式转换为SQL,无法将其视为本地表达式."

Sha*_*ica 10 c# linq linq-to-sql

我从这个问题开始,我在那里回答,现在我在这里问更基本的问题.我已将查询简化为:

var q = from ent in LinqUtils.GetTable<Entity>()
        from tel in ent.Telephones.DefaultIfEmpty()
        select new {
          Name = ent.FormattedName,
          Tel = tel != null ? tel.FormattedNumber : "" // this is what causes the error
        };
Run Code Online (Sandbox Code Playgroud)

tel.FormattedNumber是一个将字段NumberExtension字段组合成一个整齐格式的字符串的属性.这是导致的错误:

System.InvalidOperationException: Could not translate expression 'Table(Entity).SelectMany(ent => ent.Telephones.DefaultIfEmpty(), (ent, tel) => new <>f__AnonymousType0`2(Name = ent.FormattedName, Tel = IIF((tel != null), tel.FormattedNumber, "")))' into SQL and could not treat it as a local expression.
Run Code Online (Sandbox Code Playgroud)

如果我将上面的参考更改为FormattedNumber简单Number,一切正常.

但我确实希望格式化的数字在我的列表中很好地显示.你推荐什么作为最干净,最干净的方式?

Mar*_*ell 13

您可以AsEnumerable在实体上使用,但这会强制它带回所有列(即使未使用); 或许改为:

var q1 = from ent in LinqUtils.GetTable<Entity>()
         from tel in ent.Telephones.DefaultIfEmpty()
         select new {
           Name = ent.FormattedName,
           Number = (tel == null ? null : ent.Number),
           Extension = (tel == null ? null : ent.Extension)
         };

var q2 = from row in q1.AsEnumerable()
         select new {
             row.Name,
             FormattedNumber = FormatNumber(row.Number, row.Extension)
         };
Run Code Online (Sandbox Code Playgroud)

在哪里FormatNumber采取两个并合并它们的方法,可能是从你的其他(属性)代码重用.

使用LINQ-to-SQL,另一种选择是在数据上下文中公开UDF,该数据上下文执行数据库内的格式化; 一个稍微不同的例子:

var qry = from cust in ctx.Customers // and tel
          select new {
              cust.Name,
              FormattedNumber = ctx.FormatNumber(tel.Number, tel.Extension)
          };
Run Code Online (Sandbox Code Playgroud)

(这将在数据库中完成工作;这是否是一个好主意;-p)