【问题标题】:Protobuf C# Generated Class usage with Entity Framework Repeated Fields not settableProtobuf C# 生成的类使用实体框架重复字段不可设置
【发布时间】:2019-09-17 02:31:08
【问题描述】:

我在将一些 Protobuf 消息生成的 C# 类与 Entity Framework Core 集成时遇到了一些问题。在大多数情况下,我能够使用 protobuf 生成的类将信息正确地存储到 sqlite 和 mysql 数据库中。当 protobuf 消息使用重复变量时,就会出现问题。我可以通过序列化到字符串列表将重复的字段存储到数据库中,但是当尝试从数据库中读回时,我得到了这个错误。

Unhandled Exception: System.InvalidOperationException: No backing field could be found for property '<propertyname>' of entity type '<entityname>' and the property does not have a setter.

从搜索看来,设计决定是在生成 protobuf 类时,重复字段不应该只有一个 get 方法,当基于实体框架的函数试图写回解析结果时,这会导致问题到重复的字段变量中。

我想知道是否有人对解决实体框架中没有设置器这一问题的潜在方法有任何想法,或者是否有更好的方法来实现这种将 Protobuf 生成的消息存储到数据库中的功能。

作为参考,我目前有这样的实体属性设置:

entity.Property(e => e.StationTypes)
   .HasConversion(
      types => types.ToString(),
      column => ConvertToRepeatedField(column)
   );

将数据作为 JSON 样式字符串写入数据库,然后使用自定义转换转换回重复字段。

提前感谢您的帮助。

编辑:当前使用 Google.Protobuf (3.6.1) 库

【问题讨论】:

  • 您使用的是哪个 protobuf 库?谷歌? Protobuf-net?
  • 抱歉目前使用的是 Google.Protobuf 库 3.6.1

标签: c# entity-framework-core protocol-buffers


【解决方案1】:

这里的问题是对于消息:

syntax = "proto3";
message Foo {
    repeated string bar = 1;
}

protoc 生成:

  private readonly pbc::RepeatedField<string> bar_ = new pbc::RepeatedField<string>();
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
  public pbc::RepeatedField<string> Bar {
    get { return bar_; }
  }

但是这个url_ 不匹配任何预期的模式described here;具体来说,在这种情况下,EF-Core 会接受 _Bar_barm_Barm_bar - 但不会接受 bar_

如果您愿意更改库,您可以尝试使用 protobuf-net; protogen(protobuf-net 相当于 protoc)生成:

    [global::ProtoBuf.ProtoMember(1, Name = @"bar")]
    public global::System.Collections.Generic.List<string> Bars { get; }
        = new global::System.Collections.Generic.List<string>();

现在;不完全清楚 EF 是否会理解此模式或者,但这最终是 Roslyn 自动生成的模式(该字段将是 &lt;Bars&gt;k__BackingField),所以它至少是 值得一试。大多数 ORM 和序列化程序都了解 Roslyn 模式。

否则,您需要查看上述文档的后面部分,其中描述了显式配置支持字段名称的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多