将varchar值“ Zon7”转换为数据类型int时转换失败

时间:2018-09-27 10:32:11

标签: linq c#-6.0 entity-framework-core-2.1

我遇到此错误:

  

将varchar值“ Zon7”转换为数据时转换失败   输入int。

establishments = GetEstablishments(waters.Select(t => ReplaceZonToEmptyString(t.IdGeographie)));

public static int ReplaceZonToEmptyString(string zoneId)
{
     zoneId.Replace("Zon", string.Empty);
     var sbInput = zoneId.Replace(" ", string.Empty);
     return Convert.ToInt32(sbInput.ToString());
 }

 public static IQueryable<Etablissement> GetEstablishments(IQueryable<int> ids)       
 {
   return from zone in entities.Zones
          where ids.Contains(zone.IdZone)
          select zone.IdBatimentNavigation.IdEtablissementNavigation;

 }

var result = establishments.ToList();

在数据库中,我有一列类型为varchar的列,名称为“ IdGeographie ”,其值以“ Zon”开头,类似于“ ZonXXXX”

2 个答案:

答案 0 :(得分:1)

您正在尝试将VARCHAR列与类型为int的值进行比较。这些值之一必须更改,并且由于它不是SQL列,因此必须是比较值:

public static string ReplaceZonToEmptyString(string zoneId)
{
    var sbInput = new StringBuilder(zoneId);
    sbInput.Replace("Zon", string.Empty);
    sbInput.Replace(" ", string.Empty);
    return sbInput.ToString();
}

public static IQueryable<Etablissement> GetEstablishments(IQueryable<string> ids)       
{
    return from zone in entities.Zones
        where ids.Contains(zone.IdZone)
        select zone.IdBatimentNavigation.IdEtablissementNavigation;
}

如果方法的签名无法更改,则必须在GetEstablishments内进行转换:

public static IQueryable<Etablissement> GetEstablishments(IQueryable<int> ids)       
{
    var textIds = ids.Select(id => id.ToString());
    return from zone in entities.Zones
        where textIds.Contains(zone.IdZone)
        select zone.IdBatimentNavigation.IdEtablissementNavigation;
}

请注意,在waters.Select(t => ReplaceZonToEmptyString(t.IdGeographie))中,值waters必须是物化的值列表(即,不是另一个EF查询),因为替换操作在Entity Framework中无效(在这两个选项中都不能使用) )。

答案 1 :(得分:0)

您认为以下代码会做什么:

string original = "Hello World!";
string changed = original.Recplace("o", "xx");

original不会更改,changed等于“ Hellxx,Wxxrld”。

所以您应该更改ReplaceZonToEmptyString:

public static int ExtractZoneNr(string zoneId)
{
    string idWithoutZon = zoneId.Replace("Zon", string.Empty);
    string sbInput = idWithoutZon.Replace(" ", string.Empty);
    return Int32.Parse(sbInput);
}

las,这仅适用于IEnumerable,不适用于IQueryable

更好的解决方案:

仅当IdGeographie是三个字母“ Zon”后跟IdZone的字符串表示形式,并且没有其他含义时,此解决方案才有效。所以没有空格,没有前导零,例如:“ Zon4”而不是“ Zon004”,也不是“ Zon 4”

您有两个IQueryables,一个用于水域,另一个用于区域:

IQuerybale<Water> waters = ...            // probably entities.Waters
IQueryable<Zone> zones = entities.Zones

每个Zone都包含一个int属性IdZone和一个属性.IdBatimentNavigation.IdEtablissementNavigation,该属性似乎是Etablissement类型

此外,每个Water都具有字符串属性GeographieId,其格式为“ ZonX”,其中X是整数。

现在,您要查询的IdBatimentNavigation.IdEtablissementNavigation的{​​{1}}中的Zones等于一个或多个IdZone的X部分

例如:如果您具有以下Waters

Waters

您有[0] GeographieId = "Zon10" [1] GeographieId = "Zon42" [2] GeographieId = "Zon7" Zones:4、42、30、7、22。

然后,您希望IdZone中的IdBatimentNavigation.IdEtablissementNavigationZones:42个7(任意顺序)

为什么不加入水域和区域?

IdZone

更好的解决方案是尝试从IdGeographie中删除“ Zon”部分,然后将剩余的XXXX解析为一个int。 las,没有可以执行AsQueryable解析的功能。