this C# application needs to work with a MongoDB. When I try to add data, I get the error: E11000 duplicate key error collection: aap.Olas index: id dup key: { : BinData(3, 00000000000000000000000000000000) }
This is the code that adds Data to the DB
public void Add(IDataType item,string name)
{
IMongoCollection<IDataType> collection = db.GetCollection<IDataType>(name);
collection.InsertOne(item);
}
This is what the interface looks like.
using MongoDB.Bson.Serialization.Attributes;
using System;
namespace Labo04.GLOBAL
{
public interface IDataType
{
[BsonId]
Guid Id { get; set; }
}
}
This is the class Ola, the data I try to insert.
public class OLA : IDataType
{
[BsonId]
public Guid Id { get; set; }
public string Code { get; set; }
public string Naam { get; set; }
public int Studiepunten { get; set; }
public virtual List<Docent> Docenten { get; set; }
public virtual OPO Opo { get; set; }
public OLA()
{
}
public OLA(string code, string naam, int studiepunten, List<Docent> docenten, OPO opo)
{
this.Code = code;
this.Naam = naam;
this.Studiepunten = studiepunten;
this.Docenten = docenten;
this.Opo = opo;
}
}
How can I fix this.
I faced the same problem. It is because you are generating the Collection from IDataType:
db.GetCollection<IDataType>(name);
IDataType should be the final class object, so instead of passing the interface instance to this function, you can use generics:
public void Add<DataType>(DataType item,string name)
{
IMongoCollection<DataType> collection = db.GetCollection<DataType>(name);
collection.InsertOne(item);
}
Related
I am just getting started with Entity Framework Core within C#, and I'm trying to set up a class structure where one class has a field that is another class. I have found that, when the classes do not have constructors, the code runs fine. However, when I introduce a constructor as follows:
public class InterestEF
{
public InterestEF(string id, int numTimesInterestSelected, AdminEditEF lastEdit, ICollection<AdminEditEF> allEdits)
{
this.id = id;
this.numTimesInterestSelected = numTimesInterestSelected;
this.lastEdit = lastEdit;
this.allEdits = allEdits;
}
[Key]
public string id { get; set; }
public int numTimesInterestSelected { get; set; }
public AdminEditEF lastEdit { get; set; }
public virtual ICollection<AdminEditEF> allEdits { get; set; }
}
public class AdminEditEF
{
public AdminEditEF(string id, string adminIdEditedBy, DateTime dateEdited, string changesMade, string reasonsForChanges, string idOfEditedEntity, EntityTypeEdited entityTypeEdited)
{
this.id = id;
AdminIdEditedBy = adminIdEditedBy;
this.dateEdited = dateEdited;
this.changesMade = changesMade;
this.reasonsForChanges = reasonsForChanges;
this.idOfEditedEntity = idOfEditedEntity;
this.entityTypeEdited = entityTypeEdited;
}
[Key]
public string id { get; set; }
public string AdminIdEditedBy { get; set; }
public DateTime dateEdited { get; set; }
public string changesMade { get; set; }
public string reasonsForChanges { get; set; }
public string idOfEditedEntity { get; set; }
public EntityTypeEdited entityTypeEdited { get; set; }
}
public class MySQLEFContext : DbContext
{
public DbSet<AdminEditEF> AdminEdits { get; set; }
public DbSet<InterestEF> interests { get; set; }
public MySQLEFContext(DbContextOptions<MySQLEFContext> options): base(options) { }
}
I get the following error:
System.InvalidOperationException: 'No suitable constructor found for entity type 'InterestEF'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'lastEdit' in 'InterestEF(string id, int numTimesInterestSelected, AdminEdit lastEdit)'.'
Basically, I'm just wondering if it's possible to have a class that has classes as fields that also has a set of constructors with parameters I can call elsewhere within code?
Any help would be greatly appreciated.
Thank you so much for reading!
From the docs:
EF Core cannot set navigation properties (such as Blog or Posts above) using a constructor.
So you would need a constructor that looks like this:
public InterestEF(string id, int numTimesInterestSelected)
{
this.id = id;
this.numTimesInterestSelected = numTimesInterestSelected;
}
Or a parameterless one:
public InterestEF()
{
}
I have a json object and I am trying to convert it to my c# object. Here is my JSON:
{"GuvenlikNoktaArray": {"GuvenlikNoktası": [{"Id": 1,"GuvenlikNoktası1":"SANTIYE","KartNo":"000001889174217","Sira": 1},{"Id": 2,"GuvenlikNoktası1":"INSAAT","KartNo":"000000803567858","Sira": 2},{"Id": 3,"GuvenlikNoktası1":"ÇALISMA","KartNo":"000003417926233","Sira": 3},{"Id": 4,"GuvenlikNoktası1":"GÜVENLIK","KartNo":"000001888909897","Sira": 4}]}}
And my c# class:
public partial class GuvenlikNoktası
{
public GuvenlikNoktası()
{
this.GüvenlikNoktasıOlay = new HashSet<GüvenlikNoktasıOlay>();
this.PanikButonuAlarmlari = new HashSet<PanikButonuAlarmlari>();
}
public int Id { get; set; }
public string GuvenlikNoktası1 { get; set; }
public string KartNo { get; set; }
public string Sira { get; set; }
public virtual ICollection<GüvenlikNoktasıOlay> GüvenlikNoktasıOlay { get; set; }
public virtual ICollection<PanikButonuAlarmlari> PanikButonuAlarmlari { get; set; }
}
And last, my convert try:
public void AddIstasyon(string json_string)
{
GuvenlikNoktası result = new JavaScriptSerializer().Deserialize<GuvenlikNoktası>(json_string);
}
I don't get any errors but when I debuged, I see that all attributes inside 'result' are null. It seems like an empty object. How can I get a correct 'GuvenlikNoktası' object ? (Btw I am pretty sure I am getting the json object correctly).
If you must keep this JSON structure as-is you may use JObject to navigate inside your JSON properties until you reach your target objects to deserizlize. Please can you try the code below;
PS: This code uses Newtonsoft.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SO_39847703
{
class Program
{
static void Main(string[] args)
{
string json = "{\"GuvenlikNoktaArray\": {\"GuvenlikNoktası\": [{\"Id\": 1,\"GuvenlikNoktası1\":\"SANTIYE\",\"KartNo\":\"000001889174217\",\"Sira\": 1},{\"Id\": 2,\"GuvenlikNoktası1\":\"INSAAT\",\"KartNo\":\"000000803567858\",\"Sira\": 2},{\"Id\": 3,\"GuvenlikNoktası1\":\"ÇALISMA\",\"KartNo\":\"000003417926233\",\"Sira\": 3},{\"Id\": 4,\"GuvenlikNoktası1\":\"GÜVENLIK\",\"KartNo\":\"000001888909897\",\"Sira\": 4}]}}";
AddIstasyon(json);
}
public static void AddIstasyon(string json_string)
{
dynamic jsonObject = JObject.Parse(json_string);
string jsonToDeserializeStrongType = jsonObject["GuvenlikNoktaArray"]["GuvenlikNoktası"].ToString();
List<GuvenlikNoktası> result = JsonConvert.DeserializeObject<List<GuvenlikNoktası>>(jsonToDeserializeStrongType); ;
}
}
public partial class GuvenlikNoktası
{
public GuvenlikNoktası()
{
this.GüvenlikNoktasıOlay = new HashSet<GüvenlikNoktasıOlay>();
this.PanikButonuAlarmlari = new HashSet<PanikButonuAlarmlari>();
}
public int Id { get; set; }
public string GuvenlikNoktası1 { get; set; }
public string KartNo { get; set; }
public string Sira { get; set; }
public virtual ICollection<GüvenlikNoktasıOlay> GüvenlikNoktasıOlay { get; set; }
public virtual ICollection<PanikButonuAlarmlari> PanikButonuAlarmlari { get; set; }
}
public class GüvenlikNoktasıOlay
{
}
public class PanikButonuAlarmlari
{
}
}
Hope this helps
Your JSON data and your class definition do not fit together. Therefore the default values (NULL) are provided by the serializer.
In order to deserialize the given JSON data you need a class structure like:
public class Root
{
public LevelOne GuvenlikNoktaArray {get; set;}
}
public class LevelOne {
public IEnumerable<GuvenlikNoktası> GuvenlikNoktası {get; set;}
}
You can use this class.
public class GuvenlikNoktası
{
public int Id { get; set; }
public string GuvenlikNoktası1 { get; set; }
public string KartNo { get; set; }
public int Sira { get; set; }
}
public class GuvenlikNoktaArray
{
public IList<GuvenlikNoktası> GuvenlikNoktası { get; set; }
}
public class Example
{
public GuvenlikNoktaArray GuvenlikNoktaArray { get; set; }
}
You can use this link For your referencehttp://jsonutils.com/.
I've got following structure in the database:
{
"_id" : ObjectId(""),
"title" : "something",
"id" : 1,
(...)
}
Basicly i want to retrive data from following collection to my Class:
[BsonIgnoreExtraElements]
public class Topic
{
[BsonElement("id")]
public int Id { get; set; }
[BsonElement("title")]
public string Name { get; set; }
}
The problem is this code doesn't work -> executes with error message:
Cannot deserialize a 'Int32' from BsonType 'ObjectId',
but this one does:
[BsonIgnoreExtraElements]
public class Topic
{
[BsonIgnore]
public int Id { get; set; }
[BsonElement("title")]
public string Name { get; set; }
[BsonElement("id")]
public int IdTest { get; set; }
Seems like deserialization desperatly tries to match class property with name "Id" with the ObjectId in database which is not correct because i explicitly declare that i want to match it with BsonElement("id") and not ("_id").
I appreciate any ideas how to make it works as I need to.
Your "_id" stored in your mongo document is of type BsonType.ObjectId so when deserializing, the Serializer try to find a property with the name "Id" and with type of ObjectId. In your case it found matched name but not the right type which is int (int32 type in your class): my suggestion is to change
public int Id { get; set; }
to
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
Or
public ObjectId Id { get; set; }
Or to make your class inheriting from class Entity if you use MongoRepository :
[BsonIgnoreExtraElements]
public class Topic : Entity
{
[BsonElement("title")]
public string Name { get; set; }
}
I ended up doing this:
public class Topic
{
public int Id { get; set; }
public string Name { get; set; }
}
[BsonIgnoreExtraElements]
public class TopicMapper
{
[BsonElement("title")]
public string Name { get; set; }
[BsonElement("id")]
public int Identity { get; set; }
}
and this:
var list = await col.Find(new BsonDocument()).ToListAsync().ConfigureAwait(false);
foreach(var doc in list)
{
if(doc.Name != null)
topics.Add(new Topic{
Id = doc.Identity,
Name = doc.Name
});
}
I am working on an existing application that is a package tracking application and I want to append a collections list object.
My code is:
public class VehicleAssignElement
{
public VehicleAssignElement(string pkgID, string DriverID, string VehicleID)
{
pkgID = ConfID;
DriverID = puID;
VehicleID = doID;
}
public string pkgID { get; set; }
public string DriverID { get; set; }
public string VehicleID { get; set; }
}
public class VehicleAssignID
{
public List<VehicleAssignElement> AssignID { get; set; }
}
public class VehicleAssignIDList
{
public List<VehicleAssignID> AssignRecord { get; set; }
}
I have a code block where I loop through to get the pkgID.
assignElement.AssignID.Add( new VehicleAssignElement(oPackageTracking.pkgID,"",""));
I have another code block that I need to loop through to get the DriverID and a 3rd code block to loop the get the VehicleID.
Question:
How would I go about appending the collection to add DriverID as the second element and the VehicleID as the 3rd element?
Using assignElement.AssignID.Add but that adds to the collection. I tried Insert, but was unsuccessful as well.
Any advice is appreciated.
I think you meant something like this:
public class VehicleAssignElement
{
public VehicleAssignElement(string pkgID, string driverID, string vehicleID)
{
this.PkgID = pkgID;
this.DriverID = driverID;
this.VehicleID = vehicleID;
}
public string PkgID { get; set; }
public string DriverID { get; set; }
public string VehicleID { get; set; }
}
public class Form1 : Form
{
private List<VehicleAssignElement> _assignmentList = new List<VehicleAssignElement>();
public void DoSomething()
{
VehicleAssignElement assignment1 = new VehicleAssignElement("pkg1", "John", "Audi");
_assignmentList.Add(assignment1);
VehicleAssignElement assignment2 = new VehicleAssignElement("pkg2", "Morgan", "Volkswagen");
_assignmentList.Add(assignment2);
foreach(var assignment in _assignmentList)
{
Debug.WriteLine(string.Format("{0} -> {1} - {2}", assignment.PkgID, assignment.DriverID, assignment.VehicleID));
}
}
}
NOT TESTED. So it may contain some syntax errors.. But this is for example.
I have a Model like this
public class Challenge
{
public int ID { get; set; }
public string Name { get; set; }
public string Blurb { get; set; }
public int Points { get; set; }
public string Category { get; set; }
public string Flag { get; set; }
public List<string> SolvedBy { get; set; }
}
public class ChallengeDBContext : DbContext
{
public DbSet<Challenge> Challenges { get; set; }
}
and then Controller like this. But I cannot update the List "SolvedBy", the next time I step through with the debugger, the list is still empty.
[HttpPost]
public string Index(string flag = "", int id=0)
{
Challenge challenge = db.Challenges.Find(id);
if (flag == challenge.Flag)
{
var chall = db.Challenges.Find(id);
if (chall.SolvedBy == null)
{
chall.SolvedBy = new List<string>();
}
chall.SolvedBy.Add(User.Identity.Name);
db.Entry(chall).State = EntityState.Modified;
db.SaveChanges();
//congrats, you solved the puzzle
return "got it";
}
else
{
return "fail";
}
}
is there any way around it to make a list of strings kept in the database?
EF don't know how to store an array in database table so it just ignore it. You can create another table/entity or use XML/JSON to store the list. You can serialize the list before saving and deserialize it after loading from database
A List<T> in a model would normally map to a second table, but in your DbContext you only have a single table. Try adding a second table.
public class ChallengeDBContext : DbContext
{
public DbSet<Challenge> Challenges { get; set; }
public DbSet<Solution> Solutions {get; set;}
}
public class Challenge
{
public int ID { get; set; }
public string Name { get; set; }
public string Blurb { get; set; }
public int Points { get; set; }
public string Category { get; set; }
public string Flag { get; set; }
public List<Solution> SolvedBy { get; set; }
}
public class Solution
{
public int ID { get; set; }
public string Name { get; set; }
}
Then your controller can use code along the lines of...
var chall = db.Challenges.Find(id);
if (chall.SolvedBy == null)
{
chall.SolvedBy = new List<Solution>();
}
chall.SolvedBy.Add(new Solution {Name=User.Identity.Name});
None of the above has been tested and I may have made some mistakes there, but the general principle I want to illustrate is the fact that you need another table. The List<T> represents a JOIN in SQL.