1

The first if condition runs just fine, the second fails with a 'cannot cast from guid to string' error. The compiler tells me that both Ids are guids. So, why is this failing on the 2nd 'if'? l.P.Id is a guid, testP.Id is also a guid. I don't see how there's a failure here.

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();
}

After using .Any(l=>l.P.Id == testP.Id) as suggested, now all my unit tests fail with the exception System.InvalidCastException : Invalid cast from 'System.String' to 'System.Guid'.

Error stack trace as requested:

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)
MegaMark
  • 600
  • 8
  • 26
  • 1
    1. What about this field in DB. (MOAH entity, Id field) Is it uniqueidentifier? 2. I advice you to use context.GetSet().Any(l=>l.P.Id == testP.Id) in this case instead of FirstOrDefault. – ntl Aug 18 '14 at 08:44
  • From the code sample it is impossible to tell what the types of MOAH.P.Id or testP.Id is. But I bet one is a string and another is a Guid. – JacquesB Aug 18 '14 at 08:47
  • @JacquesB In VS when I check the types of the Ids, VS tells me they are both GUIDs – MegaMark Aug 18 '14 at 08:57
  • @ntl we are (sadly) using a MySql database, with fluentmigrator. The entities are setup as P.Id = char(36) and the FK column in the tables are both varchar(40)s, however, the migrator is setup as .WithColumn(PId).AsGuid().NotNullable().... and since the one test passed yet the other failed, I ruled this out as the problem. (though it still definitely could be). I tried running a migration to update the columns to .AsFixedLengthString(36) but the database does not reflect the changes after the migration is run, and the migration throws no errors.... – MegaMark Aug 18 '14 at 09:06
  • @MegaMark: So the Id *is* actually a string, but the framework tries to cast to a Guid? Look at the exception stack trace, maybe even add it to the post! – JacquesB Aug 18 '14 at 09:12
  • 1
    OK given the stack trace it seems the underlying column in the database is a string (varchar) but in the mapping it is defined as a guid. – JacquesB Aug 18 '14 at 11:11

2 Answers2

1

Try using the Guid.Parse(string guid) static method.

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();
}
Community
  • 1
  • 1
Tim.Tang
  • 3,158
  • 1
  • 15
  • 18
-1

So, I checked the database and sure enough, the new migration script to alter the column in the foreign table never ran... so after getting it to run properly and updating the column(s) to AsFixedLengthString(36) (and I have no idea why it was done this way, except to say that it's possible the table was built in by other means than fluentMigrator prior to the implementation of FM...?)... anyway this fixed the problem... though I don't want any credit for this as there would have been NO possible way for anyone else to know this... only question now is, what is the proper way to handle my post? Do I delete it?

On a side note(FWIW): never did explain why one worked whereas the other did not. They both suffered from being the wrong db type... still don't get it.

MegaMark
  • 600
  • 8
  • 26