引用含SQLite的Xamarin项目后EF6报ModelValidationException如何解决?
问题原因
- 程序集版本不匹配:Xamarin项目依赖Mono适配版本的
System.ComponentModel.DataAnnotations程序集,而ASP.NET MVC 5 + EF6项目使用的是.NET Framework官方版本的同名程序集。引用Xamarin项目后,测试项目加载的System.ComponentModel.DataAnnotations版本和EF6预期版本不一致,导致代码里添加的[Key]特性无法被EF6识别,才会抛出“未定义主键”的错误。 - EF6默认扫描策略问题:EF6初始化DbContext时,会默认扫描当前应用域中所有已加载的程序集,查找继承自DbContext、实体类、配置类的类型。如果Xamarin项目中存在和Web项目同名命名空间下的
Xx类,或者EF错误将Xamarin项目中的无关类纳入模型构建流程,也会触发该校验错误。 - EF Provider被篡改:如果Xamarin项目中携带了
EntityFramework.Sqlite等其他EF驱动包,会覆盖测试项目原本的EF驱动配置,导致EF的模型校验逻辑异常。
解决方案
1. 配置程序集绑定重定向
在测试项目的App.config文件的<runtime>节点下添加绑定规则,强制所有引用都使用Web项目对应的System.ComponentModel.DataAnnotations版本:
<dependentAssembly> <assemblyIdentity name="System.ComponentModel.DataAnnotations" publicKeyToken="31bf3856ad364e35" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="你Web项目引用的System.ComponentModel.DataAnnotations实际版本号" /> </dependentAssembly>
同时显式指定EF默认驱动,避免被Xamarin项目的SQLite驱动覆盖:
<entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework>
2. 显式限制EF的扫描范围
在ApplicationDbContext类中禁用EF的自动程序集扫描,仅加载Web项目中的实体配置:
public class ApplicationDbContext : DbContext { public ApplicationDbContext() : base("name=DefaultConnection") { Database.SetInitializer<ApplicationDbContext>(null); } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 仅从Web项目所在程序集加载实体配置 modelBuilder.Configurations.AddFromAssembly(typeof(ApplicationDbContext).Assembly); // 显式忽略Xamarin项目中的所有无关实体类型 modelBuilder.Ignore<Xamarin项目命名空间下的对应类名>(); // 保留原有其他配置 base.OnModelCreating(modelBuilder); } }
3. 拆分测试项目隔离依赖
如果不需要在同一个测试上下文中同时运行EF逻辑和Xamarin代码,可拆分测试项目:
- 原有测试项目保留,不引用Xamarin项目,专门测试Web端EF逻辑
- 新增跨端交互测试项目,通过接口、DTO传输数据,不在该项目中初始化EF的DbContext,避免依赖冲突
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

