Элемент 'Id' не соответствует ни одному полю или свойству класса

Я получил результат из коллекции в MongoDB, структура такая же, как показано ниже

[DataContract]
public class Father
{
    [BsonId]
    [DataMember]
    public MongoDB.Bson.ObjectId _id { get; set; }

    [DataMember]
    public string Id { get; set; }

    [DataMember]
    public List<Child> childs { get; set; }
}

[DataContract]
public class Child
{
    [DataMember]
    public string Id { get; set; }

    [DataMember]
    public int Name { get; set; }
}

Когда я пытаюсь это:

List<Father> f = result.ToList();

Он вызывает Element 'Id' does not match any field or property of the class Model.Child

Я думаю, что это просто берет "Id" как что-то еще.

Как я могу справиться с этим? Спасибо

Ответ 1

Я решил похожую проблему, добавив [BsonIgnoreExtraElements] поверх объявления класса. ObjectId поддерживается внутри MongoDB, который не требуется на уровне приложений, поэтому в объявлении класса это поле не требуется. Надеюсь, это поможет кому-то

Ответ 2

Я столкнулся с той же проблемой. Произошла ошибка в var data = query.ToList();

       var collection = db.GetCollection<Product>("Products");

        var query =
            from e in collection.AsQueryable<Product>()
            where e.name == "kalem"
            select e;

        var data = query.ToList();

и моя вставка:

    var collection = db.GetCollection<Product>("Products");

    collection.InsertBatch(products);

Я решил, как показано ниже.

        ObjectId id = new ObjectId();
        var collection = db.GetCollection<Product>("Products");

        collection.InsertBatch(products);
        id = pr.Id;

и я добавил id в класс Product, как показано ниже. Класс продукта

class Product
{
    public ObjectId Id { get; set; }
    public string name { get; set; }
    public string category { get; set; }
    public double price { get; set; }
    public DateTime enterTime { get; set; }
}

Ответ 3

эта работа для моего случая: добавить ярлык

    [DataMember]
    [BsonElement("songName")]

на элементы:

[BsonIgnoreExtraElements]
public class Music
{

    [BsonId]
    [DataMember]
    public MongoDB.Bson.ObjectId _id { get; set; }
    [DataMember]
    public string Id { get; set; }

    [DataMember]
    [BsonElement("songName")]
    public string SongName { get; set; }

    [DataMember]
    [BsonElement("artistName")]
    public string ArtistName { get; set; }}

Ответ 4

var conventionPack = new ConventionPack { new IgnoreExtraElementsConvention(true) };
        ConventionRegistry.Register("IgnoreExtraElements", conventionPack, type => true);

Это работает просто отлично! [BsonIgnoreExtraElements] также работал хорошо, но, если вы хотите добавить любую другую ConventionRegistry, такую как CamelCaseElementNameConvention, тогда он переопределяет атрибут Attribute, и возникает то же исключение. Не уверен, что это может быть достигнуто с помощью какого-либо другого атрибута.

Ответ 5

Ваш класс Child должен, вероятно, указывать, что он наследует отца

public class Child: Father {...}

Ваш класс Father должен, вероятно, добавить известный атрибут типа (для WCF).

[DataContract]
[KnownType(typeof(Child))]
public class Father

Если это MongoCollection ( "отцы" ), которые вы сохраняете/извлекаете, вам может потребоваться зарегистрировать карту классов для каждого ожидаемого дочернего типа.

if (!BsonClassMap.IsClassMapRegistered(typeof(Child)))
{
    BsonClassMap.RegisterClassMap<Child>(
        cm => { cm.AutoMap(); });
}

Как упоминалось в @alexjamesbrown, вам не нужно указывать поле id на вашем poco-объекте '_id'. Идея с наследованием - наследовать. Поэтому использование поля "id" Отца (независимо от того, что оно названо) должно быть достаточным. Непонятно, почему у вашего класса Father есть свойства Id и _id. Один из них, вероятно, не нужен.

Ответ 6

все, что вам нужно сделать, это удалить [DataMember] в атрибуте ObjecId и связать Id с ObjectId _id.

чтобы ваш класс выглядел так:

[DataContract]
public class Father
{
    [BsonId]
    public MongoDB.Bson.ObjectId _id { get; set; }

    [DataMember]
    public string Id { 
          get { return _id.ToString(); }
          set { _id = ObjectId.Parse(value); }
    }

    [DataMember]
    public List<Child> childs { get; set; }
}

ps: в вашем случае дочерний идентификатор должен быть сгенерирован вручную, если вы хотите, чтобы он был objectId (mongo), вы будете делать тот же трюк наконец, чтобы десериализовать объект, вы должны использовать ссылку newtonsoft.json и сделать это

Father = JsonConvert.DeserializeObject<Father>(response.Content);