2017-06-29 13 views
3

私は.NET Core(.NETStandard 1.4を対象とする)を使用して再利用可能なライブラリを作成していますが、Entity Framework Coreを使用しています。私は次のようになりますエンティティクラスがあります。EFコアを使用してエンティティフィールドにJSONを保存するにはどうすればよいですか?

public class Campaign 
{ 
    [Key] 
    public Guid Id { get; set; } 

    [Required] 
    [MaxLength(50)] 
    public string Name { get; set; } 

    public JObject ExtendedData { get; set; } 
} 

を、私はDbSetを定義するDbContextクラスを持っている:

public DbSet<Campaign> Campaigns { get; set; } 

(私はまた、DIでのリポジトリのパターンを使用していますが、私はしないでください。

)それが関連していると思う私のユニットテストは、私は、このエラーを与える:

System.InvalidOperationException: Unable to determine the relationship represented by navigation property 'JToken.Parent' of type 'JContainer'. Either manually configure the relationship, or ignore this property from the model..

は、indはする方法はありますこれは関係ではなく、大きな文字列として保存する必要がありますか?

+0

public class Campaign { // https://docs.microsoft.com/en-us/ef/core/modeling/backing-field private string _extendedData; [Key] public Guid Id { get; set; } [Required] [MaxLength(50)] public string Name { get; set; } [NotMapped] public JObject ExtendedData { get { return JsonConvert.DeserializeObject<JObject>(string.IsNullOrEmpty(_extendedData) ? "{}" : _extendedData); } set { _extendedData = value.ToString(); } } } 

バッキングフィールドとして_extendedDataを設定するには、私は私のコンテキストにこれを追加しました'ExtendedData'の型を' string'に変換してストリング化されたJSONを格納します – Michael

+0

@Michael私はそれについて考えましたが、常に有効なJSONであることを確認したいと思います。 – Alex

答えて

7

マイケルの答え@トラックに私を得たが、私は少し違っそれを実装しました。私はプライベートプロパティの文字列として値を格納し、それを "バッキングフィールド"として使用することになりました。 ExtendedDataプロパティはその後、取得にセットし、その逆に文字列にjオブジェクトを変換する:私はあなたが変更すべきだと思う

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Campaign>() 
     .Property<string>("ExtendedDataStr") 
     .HasField("_extendedData"); 
} 
+0

もオプションである可能性があります。これらのアプローチはどちらもEFコアのドキュメントにあります。バッキングフィールドはきれいに見えますが、後ほど理解しにくいかもしれません:) – Michael

+0

どちらも正しいアプローチです。唯一の違いは、EFコアがシャドウプロパティをサポートしているため、バッキングフィールドアプローチはシャドウプロパティを利用し、ドメインモデルに余分なプロパティを持たないようにすることです。 :) – Smit

2

このようなものをお試しいただけますか?ここ

[NotMapped] 
    private JObject extraData; 

    [NotMapped] 
    public JObject ExtraData 
    { 
     get { return extraData; } 
     set { extraData = value; } 
    } 

    [Column("ExtraData")] 
    public string ExtraDataStr 
    { 
     get 
     { 
      return this.extraData.ToString(); 
     } 
     set 
     { 
      this.extraData = JsonConvert.DeserializeObject<JObject>(value); 
     } 
    } 

は、移行出力されます:

ExtraData = table.Column<string>(nullable: true), 
+0

これは正しい方向だと思います。これを達成するために "Backing Fields"を使うことができるようです(https://docs.microsoft.com/en-us/ef/core/modeling/backing-field)。 – Alex

関連する問題