0

私は neo4jclient を使用しており、データ クラスの 1 つにCollection<string>プロパティがあります。

保存すると、次のエラーが発生しました。

「プロパティ 'SomeArrayPropertyName' を空の配列に設定できません。これは、その中に任意の型の値がなく、型を推測する既存のコレクションがないため、格納する配列の型を決定できないためです。 "

空の配列を Null に変更せずに保存する方法はありますか?

編集:

例:

public class BaseData
{
    public Guid Id { get; set; }
    ...
    ...
    public Collection<string> Subjects { get; set; }

    public BaseData()
    {
        Subjects = new Collection<string>();
    }

    //This method lets Json.Net know whether to serialize 'Subjects'
    public virtual bool ShouldSerializeSubjects()
    {
        return Subjects != null && Subjects.Any();
    }
}

public class ParentData : BaseData
{
}

public class ChildData : ParentData 
{
    public String Name { get; set; }
    public String Description { get; set; }
    ...
    ...
}
4

2 に答える 2

3

Neo4jclient は Json.net を使用してデータ クラスを解析するため、Json.net が検索するデータ クラスにメソッドを次の形式で追加できShouldSerializePROPERTYNAMEます(以下の例を参照)。

public class Actor
{
    public string Name { get;set;}
    public Collection<string> Alternatives { get;set; }

    //This method lets Json.Net know whether to serialize 'Alternatives'
    public bool ShouldSerializeAlternatives()
    {
        return Alternatives != null && Alternatives.Any();
    }
}

これは次のようにシリアル化さnew Actor{Name = "Jeff", Alternatives=new Collection<string>()}れます: {"Name":"Jeff"}- いいえAlternatives

明らかに、ここでの欠点は、逆シリアル化されたときにクラスに null コレクションが含まれることです。

public Actor() { Alternatives = new Collection<string>(); }

Json.Net がオブジェクトを逆シリアル化するときに呼び出されます。

IContractResolverを使用する別の方法がありますが、データ クラスにアクセスできる場合は、上記の方法が最も簡単です。

neo4j ではデータの送信が許可されないため、シリアル化しない以外に空のコレクションを回避する方法はありません。

- 編集 -

public class BaseData
{
    public Guid Id { get; set; }
    public Collection<string>  Subjects { get; set; }

    public bool ShouldSerializeSubjects()
    {
        return Subjects != null && Subjects.Any();
    }

    public BaseData()
    {
        Subjects = new Collection<string>();
    }
}

public class ParentData :BaseData {}

public class ChildData : ParentData
{
    public string Name { get; set; }
    public string Description { get; set; }
}

class Program
{
    static void Main()
    {
        var client = new GraphClient(new Uri("http://localhost.:7474/db/data/"));
        client.Connect();

        var cd = new ChildData { Name = "c1", Description = "des", Id = Guid.NewGuid() };
        var nodeRef = client.Create(cd);
        var cdRetrieved = client.Get<ChildData>(nodeRef);

        Console.WriteLine("Name: {0}, Description: {1}, Id: {2}, Subjects: {3}", cd.Name, cd.Description, cd.Id, cd.Subjects.Count);
        Console.WriteLine("Name: {0}, Description: {1}, Id: {2}, Subjects: {3}", cdRetrieved.Data.Name, cdRetrieved.Data.Description, cdRetrieved.Data.Id, cdRetrieved.Data.Subjects.Count);

        var json = JsonConvert.SerializeObject(cd);
        Console.WriteLine(json);
}

次の出力が得られます。

Name: c1, Description: des, Id: ff21b0fe-0a51-4269-a1d4-e148c905a6d7, Subjects: 0
Name: c1, Description: des, Id: ff21b0fe-0a51-4269-a1d4-e148c905a6d7, Subjects: 0
{"Name":"c1","Description":"des","Id":"ff21b0fe-0a51-4269-a1d4-e148c905a6d7"}

最後の行は、Json.Net による実際の JSON 出力で、シリアル化された「サブジェクト」はありません。

于 2013-07-30T13:18:31.497 に答える
0

Neo4j docoから貼り付け:

空の配列を格納できるのは、特定の前提条件がある場合のみです。JSON 転送形式には配列の型情報が含まれていないため、型は配列内の値から推測されます。配列が空の場合、Neo4j サーバーは型を判別できません。このような場合、指定されたプロパティに対して配列が既に格納されているかどうかを確認し、空の配列を格納するときに格納された配列タイプを使用します。アレイがまだ存在しない場合、サーバーはリクエストを拒否します。

これは、配列タイプがすでに Neo4j によって認識されている既存の配列を更新するときに、空の配列の提供が機能することを意味します。新しい配列プロパティを空にすることはできません。

于 2013-11-18T01:14:14.630 に答える