2009-12-01 125 views
0

我正在尝试使用.NET AJAX自动完成扩展。该扩展期待以下...从LINQ IQueryable对象返回字符串[]?

public static string[] GetCompletionList(string prefixText, int count, string contextKey) 

我的数据库查询是在一个LINQ var对象。我得到了编译时错误,无法将IQueryable类型转换为string []。

InventoryDataContext assets = new InventoryDataContext(); 
    var assetsInStorage = from a in assets.Assets 
          where a.Name.Contains(prefixText) 
          orderby a.Name ascending 
          select new[] { a.Manufacturer.Name, a.Name }; 
    return (string[])assetsInStorage; 
+0

我怀疑你需要替换** a.Name.Contains **,或者当* prefixText *是“Bob”时你会得到类似“Jim Bob”的值...... – NVRAM 2009-12-01 01:51:08

+0

感谢您指出这一点。我用下面的方法修正了它: let concat = a.Manufacturer.Name +“”+ a.Name +“(”+ a.AssetID +“)”+ a.ProductDivision.ProductDivision1 + a.Location.Name – omencat 2009-12-01 20:45:56

回答

8

为了在第一,你一定要得到一个string[]请选择一个字符串属性而不是匿名对象:

var assetsInStorage = from a in assets.Assets 
         where a.Name.Contains(prefixText) 
         orderby a.Name ascending 
         select a.Manufacturer.Name; // or a.Name 

assetsInStorage在这一刻是IEnumerable<string>,然后你应该把它转换为string[]由:

return assetsInStorage.ToArray(); 
+0

更好的措辞......谢谢CMS :) – 2009-12-01 01:37:09

+0

是的,我确认这个作品。是否有可能在select语句中连接两个字段? – omencat 2009-12-01 01:40:26

+0

是的...选择只需要返回一个字符串。 – 2009-12-01 01:41:42

-1

尝试:

return assetsInStorage.ToArray(); 
+0

This没有解决Enumerable 不是字符串,而是持有两个字符串数组的匿名类型的问题 – 2009-12-01 01:38:24

+0

糟糕。我在我的iPhone上查看这个,它截断了线路,我没有看到第二个参数在那里传递......这将教会我! – 2009-12-01 01:45:48

+0

@John - 实际上,OP的代码并没有创建一个拥有两个字符串数组的匿名类型 - 它只是一个由两个字符串组成的数组。所以输出是'IEnumerable '。 – 2009-12-01 05:19:47

1

assetsInStorage似乎并不为IEnumerable<string> ......正因为如此,你有投影匿名类型为字符串。

assetsInStorage.Select(a=>a[0] + a[1]) 

(或者无论你要转换的是anonymouns类型为字符串)

然后你就可以返回.ToArray()

return assetsInStorage.Select(a=>a[0]+a[1]).ToArray(); 
+0

这是'IEnumerable ',因为'IQueryable '从IEnumerable 继承。 – 2009-12-01 01:34:26

+0

是的,但T不是一个字符串,而是一个匿名类型 – 2009-12-01 01:36:24

+0

T不是一个匿名类型,而是一个字符串数组。 – 2009-12-01 05:20:43

1

这应该做的伎俩:

InventoryDataContext assets = new InventoryDataContext(); 
var assetsInStorage = from a in assets.Assets       
    where a.Name.Contains(prefixText) 
    orderby a.Name ascending 
    select String.Concat(x.ManufacturerName, " ", x.Name);  

return assetsInStorage.ToArray(); 

编辑基于评论... EF能够解释String.Concat(),所以额外的枚举是不必要的。

+1

ToList()不是必需的,不管您使用哪种框架。无论如何,底层连接关闭之前,最后的ToArray()调用将导致结果集枚举 - 无论如何强制枚举两次都没有意义。 – 2009-12-01 05:13:09

1

如果你想包含每个资产都a.Manufacturer.Namea.Name一个数组,你可以做到这一点与CMS的回答稍微修改:

var assetsInStorage = from a in assets.Assets 
         where a.Name.Contains(prefixText) 
         orderby a.Name ascending 
         select new[] { a.Manufacturer.Name, a.Name }; 

在这一点上,assetsInStorage是一个IEnumerable<string[]>这也算作IEnumerable<IEnumerable<string>>。我们可以使用SelectMany将其缩小为一个IEnumerable<string>,然后将其变成一个数组。

return assetsInStorage.SelectMany(a => a).ToArray(); 

以这种方式,您不需要只选择一个字符串值。