OrmLite升级至5.0后,C#中AddAttributes()设置模型属性失效问题
解决OrmLite 5.0动态添加属性注解不生效的问题
在OrmLite 5.0及以后的版本中,类型的元数据(包括你通过AddAttributes()动态添加的注解)会被提前缓存起来。这就导致你在运行时动态添加的属性注解,因为OrmLite已经提前读取并缓存了DataItem2的类型信息,所以后续的修改不会被识别到——这就是为什么静态注解的DataItem正常,而动态修改的DataItem2没生效的原因。
具体解决方案
要让动态添加的注解生效,你需要在完成所有属性注解的动态添加后,手动清除OrmLite的类型元数据缓存,强制它重新读取最新的类型信息。只需要在代码中添加一行关键代码:
OrmLiteConfig.ClearTypeCache();
修改后的完整代码
using ServiceStack; using ServiceStack.DataAnnotations; using ServiceStack.OrmLite; namespace OrmliteAttributeTest { class Program { static void Main(string[] args) { var type = typeof(DataItem2); type.AddAttributes(new AliasAttribute("DataItem2Table")); var prop = type.GetProperty(nameof(DataItem2.ItemKey)); if (prop != null) prop.AddAttributes(new PrimaryKeyAttribute()); prop = type.GetProperty(nameof(DataItem2.ItemDescription)); if (prop != null) prop.AddAttributes(new StringLengthAttribute(100)); // 关键步骤:清除类型缓存,让动态注解被重新识别 OrmLiteConfig.ClearTypeCache(); SqlServerDialect.Provider.GetStringConverter().UseUnicode = true; var connectionString = @"Data Source=localhost\sqlexpress; Initial Catalog=OrmLiteTest; Integrated Security=True;"; var connectionFactory = new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider); using (var db = connectionFactory.OpenDbConnection()) { db.CreateTableIfNotExists<DataItem>(); db.CreateTableIfNotExists<DataItem2>(); } } } [Alias("DataItemTable")] public class DataItem { [PrimaryKey] public int ItemKey { get; set; } [StringLength(100)] public string ItemDescription { get; set; } } public class DataItem2 { public int ItemKey { get; set; } public string ItemDescription { get; set; } } }
额外说明
ClearTypeCache()会清除所有类型的元数据缓存,不过在你的场景(初始化阶段创建表)中,这个操作完全安全,不会有副作用。- 目前OrmLite没有提供单个类型的缓存清除方法,如果需要更细粒度的操作,虽然可以通过反射访问内部缓存字典实现,但不推荐这么做——因为内部API可能会随版本变动,导致代码不稳定。
内容的提问来源于stack exchange,提问作者Peregrine
相关产品推荐
相关产品推荐

