Explosion of a compilation BUG [existing solution] caused by VS2015 Update1 update, vs2015update1

Source: Internet
Author: User

Explosion of a compilation BUG [existing solution] caused by VS2015 Update1 update, vs2015update1

A compilation BUG is no problem in the native VS2015, but after it is updated to VS2015 Update1, it is probably because Update1 uses a new compiler, which makes me suffer a lot. This problem also exists in VS2013 Update5, probably using the same compiler.

Next we will reproduce this BUG and use the simplest code to reproduce it.

Test code

A simple interface that defines a "locked" Function

1     public interface ILockable2     {3         bool IsLocked { get; set; }4     }
One entity

Similarly, a simple object definition implements the ILockable interface defined above.

1     public class TestModel : ILockable2     {3         public int Id { get; set; }4 5         public string Name { get; set; }6 7         public bool IsLocked { get; set; }8     }
EF context class

EF context class, which is also extremely simple

1     public class TestDbContext : DbContext2     {3         public TestDbContext()4             : base("default")5         { }6 7         public DbSet<TestModel> TestModels { get; set; }8     }
Interface Extension Method

To facilitate the query of all unlocked data, an IQueryable <T> extension method is defined for the entities implementing the ILockable interface. The Code is also very simple.

1     public static class Extensions2     {3         public static IQueryable<TEntity> Unlocked<TEntity>(this IQueryable<TEntity> source)4             where TEntity : ILockable5         {6             return source.Where(m => !m.IsLocked);7         }8     }
Execute the query code

Next, use the above Code for a simple query

 1     internal class Program 2     { 3         private static void Main(string[] args) 4         { 5             try 6             { 7                 var db = new TestDbContext(); 8                 var models = db.TestModels.Unlocked().ToList(); 9                 Console.WriteLine(models.Count);10             }11             catch (Exception ex)12             {13                 Console.WriteLine(ex);14             }15             Console.ReadLine();16         }17     }

So far, all the code has been displayed, which is so simple.

Exception display

The Code is also very clear, and there is no obvious problem, but in VS2015 Update1, such an exception will be reported:

"The type" RoslynBugShow. TestModel "cannot be forcibly converted to the type" RoslynBugShow. ILockable ". LINQ to Entities only supports forced conversion of EDM elements or enumeration types. "} Data: {System. collections. listDictionaryInternal} HResult:-2146233067 HelpLink: null InnerException: null Message: "The type" RoslynBugShow. testModel is forcibly converted to the type "RoslynBugShow. ILockable ". LINQ to Entities only supports forced conversion of EDM elements or enumeration types. "Source:" EntityFramework "StackTrace:" In System. data. entity. core. objects. ELinq. expressionConverter. validateAndAdjustCastTypes (TypeUsage toType, TypeUsage fromType, Type toClrType, Type fromClrType) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. getCastTargetType (TypeUsage fromType, Type toClrType, Type fromClrType, Boolean preserveCastForDateTime) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. createCastExpression (DbExpression source, Type toClrType, Type fromClrType) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. convertTranslator. translateUnary (ExpressionConverter parent, UnaryExpression unary, DbExpression operand) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. unaryTranslator. typedTranslate (ExpressionConverter parent, UnaryExpression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. typedTranslator '1. translate (ExpressionConverter parent, Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. translateExpression (Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. memberAccessTranslator. typedTranslate (ExpressionConverter parent, MemberExpression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. typedTranslator '1. translate (ExpressionConverter parent, Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. translateExpression (Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. notTranslator. typedTranslate (ExpressionConverter parent, UnaryExpression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. typedTranslator '1. translate (ExpressionConverter parent, Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. translateExpression (Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. translateLambda (LambdaExpression lambda, DbExpression input) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. translatelamsion( LambdaExpression lambda, DbExpression input, DbExpressionBinding & binding) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. methodCallTranslator. oneLambdaTranslator. translate (ExpressionConverter parent, MethodCallExpression call, DbExpression & source, DbExpressionBinding & sourceBinding, DbExpression & lambda) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. methodCallTranslator. oneLambdaTranslator. translate (ExpressionConverter parent, MethodCallExpression call) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. methodCallTranslator. sequenceMethodTranslator. translate (ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. methodCallTranslator. typedTranslate (ExpressionConverter parent, MethodCallExpression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. typedTranslator '1. translate (ExpressionConverter parent, Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. translateExpression (Expression linq) \ r \ n in System. data. entity. core. objects. ELinq. expressionConverter. convert () \ r \ n in System. data. entity. core. objects. ELinq. ELinqQueryState. getExecutionPlan (Nullable '1 forMergeOption) \ r \ n in System. data. entity. core. objects. objectQuery '1. <> c _ DisplayClass7. <GetResults> B _ 6 () \ r \ n in System. data. entity. core. objects. objectContext. executeInTransaction [T] (Func '1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) \ r \ n in System. data. entity. core. objects. objectQuery '1. <> c _ DisplayClass7. <GetResults> B _ 5 () \ r \ n in System. data. entity. sqlServer. defaultSqlExecutionStrategy. execute [TResult] (Func '1 operation) \ r \ n in System. data. entity. core. objects. objectQuery '1. getResults (Nullable '1 forMergeOption) \ r \ n in System. data. entity. core. objects. objectQuery '1. <System. collections. generic. IEnumerable <T>. getEnumerator> B _ 0 () \ r \ n in System. data. entity. internal. lazyEnumerator '1. moveNext () \ r \ n in System. collections. generic. list '1 .. ctor (IEnumerable '1 collection) \ r \ n in System. linq. enumerable. toList [TSource] (IEnumerable '1 source) \ r \ n in RoslynBugShow. program. main (String [] args) Location d: \ documents \ visual studio 2015 \ Projects \ RoslynBugShow \ Program. cs: Row 14 "TargetSite: {System. data. entity. core. metadata. edm. typeUsage ValidateAndAdjustCastTypes (System. data. entity. core. metadata. edm. typeUsage, System. data. entity. core. metadata. edm. typeUsage, System. type, System. type)
BUG Analysis

When you see this, it is estimated that you can understand it. The code looks really okay. Why is there a problem? What is the more force conversions.

Anyway, I am entangled in vomiting blood here and thought it was a matter of entity design (in actual projects, entity design is of course much more complicated than above, troubleshooting is much more difficult). Later, I accidentally checked the decompilation code to find out the culprit. Next I will compare the compilation of the Unlocked Extension Method on the two compilers of VS2015 Update1 and VS2015:

Native VS2015 Compilation

VS2015 Update1 Compilation

From the decompilation code above, we can see that the compilation result of VS2015 Update1 has a forced conversion, but this forced conversion is not supported in the Linq To Entities, so it is reported

You cannot forcibly convert the type "RoslynBugShow. TestModel" to the type "RoslynBugShow. ILockable ". LINQ to Entities only supports forced conversion of EDM elements or enumeration types.

This exception.

The problem has risen to the compiler level, which is not solved by our civilian code farm. We can only expect Microsoft to solve it in the next update of VS2015.

Solution

Indeed, there are many cattle in the garden, and @ Choo on the 29 th floor provides a perfect solution to this problem.

ClassRestrictions: VS2015 Update1 and VS2015 compilation results are exactly the same, and the problem is solved successfully!

 

DEMO code download: RoslynBugShow.rar

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.