【问题标题】:Error comparing guid to guid in linq将 guid 与 linq 中的 guid 进行比较时出错
【发布时间】:2014-10-11 03:05:00
【问题描述】:

第一个 if 条件运行良好,第二个失败并出现“无法从 guid 转换为字符串”错误。编译器告诉我两个 ID 都是 guid。那么,为什么在第二个“if”中失败了? l.P.Id 是一个 guid,testP.Id 也是一个 guid。我看不出这里有什么失败之处。

if (context.GetSet<PBM>().FirstOrDefault(l=>l.P.Id == testP.Id) != null)
{
    context.GetSet<PBM>()
           .Remove(context.GetSet<PBM>()
           .FirstOrDefault(l => l.P.Id == testP.Id));
    context.SaveChanges();
}

if (context.GetSet<MOAH>().FirstOrDefault(l=>l.P.Id == testP.Id) != null)
{
    context.GetSet<MOAH>()
           .Remove(context.GetSet<MOAH>()
           .FirstOrDefault(l => l.P.Id == testP.Id));
    context.SaveChanges();
}

按照建议使用.Any(l=&gt;l.P.Id == testP.Id) 后,现在我的所有单元测试都失败了,但System.InvalidCastException : Invalid cast from 'System.String' to 'System.Guid'. 除外

请求的错误堆栈跟踪:

System.InvalidCastException : Invalid cast from 'System.String' to 'System.Guid'.
   at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at MySql.Data.Entity.EFMySqlDataReader.ChangeType(Object sourceValue, Type targetType)
   at MySql.Data.Entity.EFMySqlDataReader.GetValue(Int32 ordinal)
   at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal)
   at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.GetColumnValueWithErrorHandling(Int32 ordinal)
   at lambda_method(Closure, Shaper)
   at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
   at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
   at System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source)
   at System.Linq.Queryable.FirstOrDefault(IQueryable`1 source, Expression`1 predicate)

【问题讨论】:

  • 1. DB中的这个字段怎么样。 (MOAH 实体,Id 字段)是唯一标识符吗? 2. 我建议你在这种情况下使用 context.GetSet().Any(l=>l.P.Id == testP.Id) 而不是 FirstOrDefault。
  • 从代码示例中无法判断 MOAH.P.Id 或 testP.Id 的类型是什么。但我敢打赌,一个是字符串,另一个是 Guid。
  • @JacquesB 在 VS 中,当我检查 Id 的类型时,VS 告诉我它们都是 GUID
  • @ntl 我们(遗憾地)使用带有 fluentmigrator 的 MySql 数据库。实体设置为 P.Id = char(36) 并且表中的 FK 列都是 varchar(40)s,但是,迁移器设置为 .WithColumn(PId).AsGuid().NotNullable().. ..并且由于一个测试通过而另一个失败,我排除了这个问题。 (尽管它仍然可以肯定)。我尝试运行迁移以将列更新为 .AsFixedLengthString(36) 但迁移运行后数据库未反映更改,并且迁移不会引发任何错误....
  • OK,鉴于堆栈跟踪,数据库中的基础列似乎是一个字符串 (varchar),但在映射中它被定义为一个 guid。

标签: c# linq guid


【解决方案1】:

尝试使用Guid.Parse(string guid) 静态方法。

Cast string as Guid using LinqPad

var pid=Guid.Parse(testP.Id);
if (context.GetSet<PBM>().Any(l=>l.P.Id == pid) )
{
    context.GetSet<PBM>()
           .Remove(context.GetSet<PBM>()
           .FirstOrDefault(l => l.P.Id == pid));
    context.SaveChanges();
}

if (context.GetSet<MOAH>().Any(l=>l.P.Id == pid))
{
    context.GetSet<MOAH>()
           .Remove(context.GetSet<MOAH>()
           .FirstOrDefault(l => l.P.Id == pid));
    context.SaveChanges();
}

【讨论】:

  • 这不会解决问题,因为问题出在映射中。
【解决方案2】:

所以,我检查了数据库,果然,用于更改外部表中的列的新迁移脚本从未运行过......所以在让它正常运行并将列更新为 AsFixedLengthString(36) 之后(和我不知道为什么要这样做,只是说桌子可能是内置的 在实施 FM 之前通过 fluentMigrator 以外的其他方式......?)......无论如何,这解决了问题......虽然我不想要任何功劳,因为会有 NO 其他人知道这一点的可能方式......现在唯一的问题是,处理我的帖子的正确方法是什么?我删除它吗?

附带说明(FWIW):从来没有解释为什么一个工作而另一个没有。他们遭受了错误的数据库类型...仍然不明白。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多