【问题标题】:EF Code First specify how to store a scalar propertyEF 代码首先指定如何存储标量属性
【发布时间】:2012-12-12 10:09:23
【问题描述】:

我想知道 EF Code First 中是否有一种方法可以指定如何存储此示例的标量属性:

我有这个 POCO 对象:

public class MyObject
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public ICollection<Url> Urls { get; set; }
}

有没有办法告诉 EF 使用 protobuff 和地图或任何其他机制将 Urls 存储为 byte[]?

【问题讨论】:

    标签: ef-code-first entity-framework-5


    【解决方案1】:

    没有,除非您直接在 MyObject 类中创建第二个 byte[] 属性。然后您将映射一个新属性并忽略旧属性。一旦你有了这个映射,你是否将转换逻辑直接包含到类中(到 Urls 属性的 getter 和 setter)或者如果你使用覆盖 SaveChanges 和处理程序 ObjectContext.ObjectMaterialized 在范围内进行转换数据访问基础设施。

    如果您选择了,您将无法通过 Urls 进行查询。 EF 唯一可见的属性是新的字节数组。

    【讨论】:

    • 我使用了两个属性的技巧,我不太喜欢它,但现在我将继续使用它!谢谢
    【解决方案2】:

    不,我认为不可能直接指示 EF 将项目集合存储为 byte[],但您可以使用一些解决方法。

    NotMapped 属性添加到Urls 属性-它从EF 模型中排除属性,然后添加另一个属性SerializedUrls,它将包含您序列化为字节[] 的集合,并将其保存到数据库中。最后通过 getter/setter 同步 UrlsSerializedUrls 属性。

    private byte[] _serializedUrls;
    private ICollection<Url> _urls;
    
    public byte[] SerializedUrls { 
      get { return _serializedUrls; }
      set {
        _urls = this.Deserialize(value);
        _serializedUrls = value;
      }
    }
    
    [NotMapped]
    public ICollection<Url> Urls {
      get { return _urls; }
      set { 
        _urls = value;
        _serializedUrls = this.Serialize(value);        
      }
    }
    
    private byte[] Serialize(ICollection<Url> collection) {
      //call protobuf to serialize data
    }
    
    private ICollection<Url> Deserialize(byte[] data) {
      //call protobuf to deserialize data
    }
    
    public void UpdateSerializedValue() {
      serializedUrls = this.Serialize(_urls);
    }
    

    注意:由于集合的二进制表示在您添加/删除/更改集合中的项目时会发生变化,因此如果集合的内容发生更改,请确保更新 SerializedUrls

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-07
      • 2020-10-08
      相关资源
      最近更新 更多