[英]Is there way to use protobuf-csharp-port generated classes with servicestack.ormlite?
I have a ton of C# classes generated using protobuf-csharp-port. 我有很多使用protobuf-csharp-port生成的C#类。 I ended up creating my own simple ORM mechanism for them.
我最终为他们创建了自己的简单ORM机制。
Turns out OrmLite is exactly what I want. 原来OrmLite正是我想要的。 But I'm now "stuck" with protobuf classes.
但是我现在被protobuf类“迷住了”。 Biggest issue is that for each entity, I have two classes: EntityClass (which is readonly) and EntityClass.Builder.
最大的问题是,对于每个实体,我都有两个类:EntityClass(只读)和EntityClass.Builder。
Is there any way to integrate OrmLite and protobuf-csharp-port classes (and their builders)? 有没有办法整合OrmLite和protobuf-csharp-port类(及其构建器)?
I managed to make it work like this: 我设法使它像这样工作:
I created a InitProtoTable extension to IDbConnection which needs to be called for every proto, in the very start of the program, like: 我为IDbConnection创建了一个InitProtoTable扩展,需要在程序的开头为每个原型调用该扩展,例如:
var dbFactory = new OrmLiteConnectionFactory(...);
var db = dbFactory.Open();
db.InitProtoTable<Person.Builder>();
After that, one can call OrmLite methods: 之后,可以调用OrmLite方法:
db.DropTable<Person.Builder>();
db.CreateTable<Person.Builder>();
The extension looks like this: 扩展名如下所示:
public static class OrmLiteExtensions
{
public static void InitProtoTable<B>(this IDbConnection db)
where B : IBuilder, new()
{
var desc = new B().DescriptorForType;
var model = ModelDefinition<B>.Definition;
model.Name = desc.Name;
model.IgnoredFieldDefinitions.Clear();
var fieldList = new List<FieldDefinition>();
var fieldMap = desc.Fields
.ToDictionary(f => f.Name, StringComparer.OrdinalIgnoreCase);
foreach (var field in model.FieldDefinitions)
{
if (fieldMap.ContainsKey(field.Name)) fieldList.Add(field);
}
model.FieldDefinitions = fieldList;
model.AfterInit();
if (db.TableExists<B>())
{
var columns = GetColumnNames<B>(db, model.ModelName);
var missing = model.FieldDefinitions
.Where(field => !columns.Contains(field.FieldName));
foreach (var field in missing)
{
field.DefaultValue = fieldMap[field.Name].DefaultValue.ToString();
db.AddColumn(typeof(B), field);
Console.WriteLine(db.GetLastSql());
}
}
}
private static HashSet<string> GetColumnNames<T>(IDbConnection db, string tableName)
{
using (var cmd = db.CreateCommand())
{
// Workaround to RDMS agnostic table column names discovery.
cmd.CommandText = string.Format("SELECT * FROM {0} WHERE 1!=1", tableName);
var table = new DataTable();
table.Load(cmd.ExecuteReader());
return new HashSet<string>(
table.Columns.OfType<DataColumn>().Select(c => c.ColumnName));
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.