var items = from c in contacts
            select new ListItem
            {
                Value = c.ContactId, //Cannot implicitly convert type 'int' (ContactId) to 'string' (Value).
                Text = c.Name
            };
var items = from c in contacts
            select new ListItem
            {
                Value = c.ContactId.ToString(), //Throws exception: ToString is not supported in linq to entities.
                Text = c.Name
            };


反正我能做到吗?严格遵守C#!!

评论

.ToString()也不适用于VB中的LinqToEF。恕我直言,有点愚蠢。

@StingyJack,问题出在ELINQ(linq 2实体)上,因为它将代码转换为SQL,而对于内部ToString请求,它不知道如何将“ ToString”转换为SQL。与linq 2对象不同,当没有翻译并且所有内容都是CLR lambda时,它将直接在请求的对象上执行。

我很生气,他们允许编译这种错误,并且我不得不永远拖延才能找到原因的简单英语描述(无法律用语和学术用语)。

您是对的,但他们也是对的,不应该将所有CLR和自定义的CLR功能转换为SQL,尤其是在EF的早期版本中:)关于ToString,请阅读Brian的回答:stackoverflow。 com / questions / 1066760 /…

太好了,但是使用3.5(不是4)的人呢?那怎么了?

#1 楼

借助EF v4,您可以使用SqlFunctions.StringConvert。 int没有重载,因此您需要转换为双精度或十进制。您的代码最终看起来像这样:

var items = from c in contacts
            select new ListItem
            {
                Value = SqlFunctions.StringConvert((double)c.ContactId).Trim(),
                Text = c.Name
            };


评论


为什么在地球上它们不包含int的重载?

– Jeremy Coenen
2010年10月1日于16:59

@Nestor这不适用于SQL Compact。发现了很难的方法。

–奥斯丁
11年8月8日在21:04

为避免结果前出现空格,应使用SqlFunctions.StringConvert((double)c.ContactId).Trim()

– Kim Tranjan
2012-3-15的3:47

似乎不适用于使用System.Data.SQLite的SQLite在Typw'System.Data.Objects.SqlClient.SqlFunctions'中的方法'System.String StringConvert(System.Nullable`1 [System.Double])'可以从“ LINQ to Entities”到übersetztwerden。 (无法翻译为“ LINQ to Entities”)

– OneWorld
2013年1月9日在10:28



很好的答案!请注意,从使用EF 6开始,该类已移至另一个名称空间。因此,在EF 6之前,您应该包括:“ System.Data.Objects.SqlClient”如果更新到EF 6,或者只是在使用此版本,请包括:“ System.Data.Entity.SqlServer” EF6,代码可以很好地编译,但是会引发运行时错误。我希望此注释有助于避免混淆。

–狮子座
16-12-22在15:27



#2 楼

我通过将整数到字符串的转换置于查询之外,解决了类似的问题。这可以通过将查询放入对象中来实现。

var items = from c in contacts
            select new 
            {
                Value = c.ContactId,
                Text = c.Name
            };
var itemList = new SelectList();
foreach (var item in items)
{
    itemList.Add(new SelectListItem{ Value = item.ContactId, Text = item.Name });
}


评论


这是解决问题的一种方法,但是请记住,这将增加执行时间,如果您有大量对象,则此foreach是过大的...

– Serlok
19年7月12日在10:26



#3 楼

使用LinqToObject:contact.AsEnumerable()

var items = from c in contacts.AsEnumerable()
            select new ListItem
            {
                Value = c.ContactId.ToString(),
                Text = c.Name
            };


评论


谢谢。仅供参考,我正在尝试解决一个稍微不同的问题。我对实体/ lambda使用LINQ,这有效。我试图将Int转换为String并使用“包含”来查找匹配的结果->即db.contacts.AsEnumerable()。Where(c => c.ContactId.ToString()。Contains(searchitem))。ToList (); ;

– ejhost
2014-12-5 18:49



如果您调用AsEnumerable,则您将为大型数据库支付高性能的价格,因为它将所有内容带入内存。 IEnumerable与IQueryable相比要慢一些,因为后者是在数据库中专门执行的。

– CodeArtist
2015年6月26日19:40

#4 楼

SqlFunctions.StringConvert可以工作,但是我觉得它很麻烦,而且在大多数情况下,我并不需要在SQL端执行字符串转换。

如果我想怎么办要进行字符串操作,请先在linq-to-entities中执行查询,然后再在linq-to-objects中进行字符串操作。在此示例中,我想获取一组包含联系人全名和ContactLocationKey的数据,ContactLocationKey是两个Integer列(ContactID和LocationID)的字符串隐式表示。 />现在,我同意必须编写两个匿名选择确实很麻烦,但是我认为这样做不方便,因为您可以方便地执行L2E中不支持的字符串(和其他)函数。另外请记住,使用此方法可能会降低性能。

#5 楼

public static IEnumerable<SelectListItem> GetCustomerList()
        {
            using (SiteDataContext db = new SiteDataContext())
            {
                var list = from l in db.Customers.AsEnumerable()
                           orderby l.CompanyName
                           select new SelectListItem { Value = l.CustomerID.ToString(), Text = l.CompanyName };

                return list.ToList();
            }
        }


评论


您是否测试过并且可以正常工作?请先阅读此答案。

– Shimmy Weitzhandler
2011年4月30日在21:48

是的,我已经在使用它。它适用于MVC3,EF4,CTP5,SQL CE4。

– Nestor
2011年5月1日,11:50



这似乎比将其装箱并使用StringConvert进行拳击更为优雅。

– CmdrTallen
2011年7月23日14:21在

但是在这种情况下,您将从数据库中获取所有数据,然后假设您要在返回list.ToList();之前对该列表进行一些过滤。 !!

–瓦希德·比塔尔(Wahid Bitar)
2011年9月26日在21:48

当您无法访问SqlFunctions时,您没有其他选择。但是,我会在查询中使用它:return(从db.Customers orderby l.CompanyName中的l选择new {Id = l.CustomerID,Name = l.CompanyName})。AsEnumerable()。Select(c => new SelectListItem {Value = c.Id.ToString(),Text = c.Name})。ToList();。这样做只能从数据库中获取ID /名称(而不是所有客户属性),并使用数据库上更有效的索引进行排序。

– Brian Bauthon
2011年9月27日19:05

#6 楼

var selectList = db.NewsClasses.ToList<NewsClass>().Select(a => new SelectListItem({
    Text = a.ClassName,
    Value = a.ClassId.ToString()
});


首先,转换为对象,然后toString()将是正确的。

#7 楼

Brian Cauthon的答案非常好!对于EF 6,只需稍作更新,该类便移至另一个名称空间。因此,在EF 6之前,您应该包括:

System.Data.Objects.SqlClient


如果您更新到EF 6,或者只是使用此版本,请包括: >
System.Data.Entity.SqlServer


通过在EF6中包含不正确的名称空间,代码可以很好地编译,但会引发运行时错误。我希望此注释有助于避免混淆。

评论


我不得不说,您的回答也很好。我升级到EF6,并且到处都在寻找SqlFunctions。您的回答为我指明了正确的方向。我将添加您还需要对EntityFramework.SqlServer的引用(您可能仅对EntityFramework的引用)。

–元数据
17年4月17日在18:12

#8 楼

当我将我的MVC 2应用程序转换为MVC 3时遇到了同样的问题,只是为了给这个问题提供另一个(干净的)解决方案,我想发布我所做的......

IEnumerable<SelectListItem> producers = new SelectList(Services.GetProducers(),
    "ID", "Name", model.ProducerID);


GetProducers()仅返回生产者的实体集合。
P.S. SqlFunctions.StringConvert对我不起作用。

#9 楼

如果您的“联系人”充当通用列表,希望以下代码能正常工作。

var items = contact.Distinct().OrderBy(c => c.Name)
                              .Select( c => new ListItem
                              {
                                Value = c.ContactId.ToString(),
                                Text = c.Name
                              });


谢谢。

#10 楼

另一种解决方案:

c.ContactId + ""


只需添加空字符串,它将转换为字符串。

评论


返回的错误:System.NotSupportedException:无法将类型“ System.Int64”强制转换为类型“ System.Object”。 LINQ to Entities仅支持强制转换EDM基本类型或枚举类型。

– QMaster
18年8月11日在7:20

#11 楼

使用MySql,SqlFunctions.StringConvert对我不起作用。由于我在项目的20多个地方使用了SelectListItem,因此我想要一个在不扭曲20多个LINQ语句的情况下工作的解决方案。我的解决方案是将SelectedListItem子类化,以提供一个整数设置器,该设置器使类型转换脱离LINQ。显然,此解决方案很难推广,但对我的特定项目很有帮助。

要使用此方法,请创建以下类型并在LINQ查询中使用,代替SelectedListItem,并使用IntValue代替Value 。

public class BtoSelectedListItem : SelectListItem
{
    public int IntValue
    {
        get { return string.IsNullOrEmpty(Value) ? 0 : int.Parse(Value); }
        set { Value = value.ToString(); }
    }
}


#12 楼

如果您使用实体框架,并且希望使唯一的int可以接受,则可以在linq查询中使用它,您可以尝试使用此方法。

)会将您的值转换为int,这样您就不需要将字符串转换为int,就可以得到想要的结果。

这对我的项目很有用,我认为这对你

#13 楼

我的理解是,您必须创建一个局部类来“扩展”模型并添加一个只读属性,该属性可以利用该类的其余属性。

public partial class Contact{

   public string ContactIdString
   {
      get{ 
            return this.ContactId.ToString();
      }
   } 
}


然后

var items = from c in contacts
select new ListItem
{
    Value = c.ContactIdString, 
    Text = c.Name
};


评论


不,您不能在LINQ to Entities中使用自定义属性(在.NET 3.5中)。

– Craig Stuntz
09年7月1日在12:33

我没有对其进行测试,但是它也不起作用。因为它不是表字段属性。我可以先使用ToArray()进行操作,然后对对象进行临清操作,但是我想查询数据库。我认为将无法做到。我创建了自己的ListItem,它接受一个int字段。这对我来说更好。

– Shimmy Weitzhandler
09年7月1日在13:06

#14 楼

var items = from c in contacts
select new ListItem
{
    Value = String.Concat(c.ContactId), //This Works in Linq to Entity!
    Text = c.Name
};


我发现SqlFunctions.StringConvert((double)c.Age)不适用于我,或者该字段属于Nullable<Int32>类型。这。

希望对一些编码人员有所帮助。

评论


对我不起作用。它将引发异常“ ...无法将System.String Concat(System.Object)转换为存储表达式...”。

– Slauma
13年5月5日在19:26

也不适合我。我还收到“ System.NotSupportedException:LINQ to Entities无法识别方法'System.String Concat(System.Object)',并且该方法无法转换为商店表达式。”

–camainc
2013年9月3日19:07



不起作用-致力于解决此问题[NotSupportedException:LINQ to Entities无法识别方法'System.String Concat(System.Object)',并且该方法无法转换为商店表达式。]

–菲利普·穆宁(Philipp Munin)
13-10-25在17:02



#15 楼

您可以尝试:

var items = from c in contacts
        select new ListItem
        {
            Value = Convert.ToString(c.ContactId), 
            Text = c.Name
        };


评论


上面的代码将不起作用,因为它将引发一个错误:“ LINQ to Entities无法识别方法'System.String ToString(Int32)',并且该方法无法转换为商店表达式”。

– G K
14年6月18日在6:05