简体   繁体   English

有没有办法将protobuf-csharp-port生成的类与servicestack.ormlite一起使用?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM