Let me explain my problem.
So I have JSON:
{"num":20, "meta":[{"id":312, "identif":{"type":true,"status":false}}}]}
I am currently grabbing the meta id field with:
var id = JsonConvert.DeserializeObject<typeObj>
(returnJSON(ApiUrl)).meta[0].id;
class to refrence:
class typeObj
{
public int num {get; set; }
public List<metatypes> meta {get; set;}
}
class metatypes
{
public int id {get; set;}
}
The issue doesn't lay here though. I am trying to get the indentif status element from meta.
I have tried putting a list in metatypes like:
class metatypes
{
public int id {get; set;}
public List<idtypes> identif {get; set;}
}
class idtypes
{
public bool type {get; set;}
public bool status {get; set;}
}
Calling it with:
var id = JsonConvert.DeserializeObject<typeObj>
(returnJSON(ApiUrl)).meta[0].identif[0].status;
But when I try this it returns
'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1'
Looked around and couldn't find a direct solution to my problem.
You have an incorrect json for the desired structure:
Given classes:
class typeObj
{
public int num {get; set; }
public List<metatypes> meta {get; set;}
}
class metatypes
{
public int id {get; set;}
public List<idtypes> identif {get; set;}
}
class idtypes
{
public bool type {get; set;}
public bool status {get; set;}
}
Your json should look like (identif must be an array): (.NET Fiddle)
{"num":20, "meta":[{"id":312, "identif":[{"type":true,"status":false}]}]}
For the json in question your classes should be like this: (.NET Fiddle)
class typeObj
{
public int num {get; set; }
public List<metatypes> meta {get; set;}
}
class metatypes
{
public int id {get; set;}
public idtypes identif {get; set;}
}
class idtypes
{
public bool type {get; set;}
public bool status {get; set;}
}
Related
I store my data with this data structure in Elasticsearch:
class Parent {
public guid Id {get; set;}
public string Name {get; set;}
public string Description {get; set;}
public List<Child> Children {get; set;}
}
class Child
{
public float Score{get; set;}
public int QTY {get; set;}
public string Name {get; set;}
}
Now I want to find the parents who have a child with a Score more than 6 and QTY more than 4. How can I provide the property Path of this fields in my query. I didn't store children as nestet object in the parent.
Hi I have a simple database, and what I am trying to do is build simple include maps as string using eager loading mechanism in EF CORE.
So in other words mu db models looks like:
And models that are supporting them:
public class StartTable
{
public int Id {get; set;}
public ICollection<TableA> TableA {get; set;}
public ICollection<TableB> TableA {get; set;}
}
public class TableA
{
public int Id {get; set;}
public StartTable StartTable {get; set;}
public int StartTableId {get; set;}
public TableAChild TableAChild {get; set;}
public int TableAChildId {get; set;}
public TableAB TableAB {get; set;}
public int TableABId {get; set;}
}
public class TableB
{
public int Id {get; set;}
public StartTable StartTable {get; set;}
public int StartTableId {get; set;}
public TableBChild TableBChild {get; set;}
public int TableBChildId {get; set;}
public TableAB TableAB {get; set;}
public int TableABId {get; set;}
}
public class TablAChild
{
public int Id {get; set;}
public TableA TableA {get; set;}
}
public class TableBChild
{
public int Id {get; set;}
public TableB TableB {get; set;}
}
public class TableAB
{
public int Id {get; set;}
public TableA TableA {get; set;}
public TableB TableB {get; set;}
}
I think relations are readible from models. Now I just want to create a map, that is I want to select start table and with include of all branches so final include path should looks like:
_context.StartTable.Include("StartTable.TableA.TableAChild")
_context.StartTable.Include("StartTable.TableA.TableAB")
_context.StartTable.Include("StartTable.TableB.TableBChild")
_context.StartTable.Include("StartTable.TableB.TableAB")
And If I type this manually it works, but this will grow a lot so I don't want to update this every time something will come up, I tried AutoInclute() in context on main table but it includes only 1 level down.
I thought I can create some sort of map function that looks like:
private static IEnumerable<string> BuildIncludeTree(DbContext context, Type type)
{
var entityAssemblyTypes = Assembly.GetExecutingAssembly().GetReferencedAssemblies().SelectMany(assembly => Assembly.Load(assembly).GetTypes());
void AddAssetByString(ref HashSet<string> navigation, List<string> createdPaths)
{
foreach (var path in createdPaths)
{
var splitPath = path.Split('.');
var relationNavigationNode = splitPath.Last();
var parentNavigationType = entityAssemblyTypes.FirstOrDefault(t => t.Name == relationNavigationNode);
if (parentNavigationType == null)
{
throw new ArgumentException($"Unknown type parent: {relationNavigationNode}");
}
var parentNodesProperties =
parentNavigationType.GetProperties().Where(prop => !prop.PropertyType.IsSimple() && !splitPath.Contains(prop.Name)).ToArray();
if (!parentNodesProperties.Any())
{
navigation.Add(path);
continue;
}
navigation.Add(path);
AddAssetByString(ref navigation, parentNodesProperties.Select(prop => $"{path}.{prop.Name}").ToList());
}
}
IEntityType entityType = context.Model.FindEntityType(type);
if (entityType == null) throw new ArgumentException($"Unknown entity type {type.Name}");
var navigationsByString = new HashSet<string>();
var relationsByString = entityType.GetNavigations().Select(nav => $"{type.Name}.{nav.Name}");
AddAssetByString(ref navigationsByString, relationsByString.ToList());
return new List<string>();
}
But problem here is relation to TableAB, I mean when I get to mapping this part function goes circular and creates map:
StartTable.TableA.TableAChild.TableB.StartTable.TableA ... and so on
Can this be prevented and what am I missing?
Can EF Core detect in some sort of way navigation downwards and upwards?
Or is there any other and simpler way to do that?
You can't Include all .There is already post about that here
Is there a way to Include() all with dbcontext?
But if correctly understand you can use Linq to make you code shorter like:
_context.StartTable.Include(x => x.TableA.TableAChild && x.TableA.TableAB && x. ....)
And in that case you will need to add entities you want to include in your class also you can use [NotMapped] attribute if you working direct with your class instead of dto. So in that way you can access the mapped entities direct from the class like class.TableAChild
+
public virtual TableAChild TableAChild { get; set; }
public virtual TableAB TableAB { get; set; }
Greetings and good luck
I have a structure like this.
public class particleProperty
{
public Point3 point_A {get; set;}
public Point3 point_B {get; set;}
public int hashEdge {get; set;}
public int vertOne {get; set;}
public int vertTwo {get; set;}
}
public Dictionary<int, List<particleProperty>> particleEdges = new Dictionary<int, List<particleProperty>>();
how can i obtain Keys from dictionary by hashEdge, for example?
I am trying to work out how to add a reference an object from within EF.
I little hard to explain so I thought I would share a dotnetfiddle example
https://dotnetfiddle.net/4n5Flk
public class ReportConfig
{
[Key]
public int ReportConfigKey {get; set;}
public int ConfigTypeKey {get; set;}
public int ConfigValue {get; set;}
[ForeignKey("ConfigTypeKey")]
public virtual <ConfigType> ConfigType {get; set;}
}
public class ConfigType
{
[Key]
public int ConfigTypeKey {get; set;}
//This can be
//Address
//Car etc etc.
public string ConfigName {get; set;}
}
public class Car
{
[Key]
public int CarId {get; set;}
//other items
}
public class Address
{
[Key]
public AddressId {get; set;}
}
In a nutshell I am trying to create a navigation property to either a car or an address based on the ConfigValue and the ConfigTypeKey
I was thinking to create 2 navigation properties "Car" and "Address" and for both add 2 foreign key's 1 to the object and 1 as a hardcoded reference to ConfigName as Car or Address
is this possible atall
Sorry for the poor explanation.
My classes (and tables):
class A {
public int Id {get; set;}
public string Name {get; set;}
public virtual C CField {get; set;}
}
class B {
public int Id {get; set;}
public string Name {get; set;}
public DateTime Date {get; set;}
public virtual C CField {get; set;}
}
class C {
public int Id {get; set;}
public string Name {get; set;}
}
class D {
public int Id {get; set;}
public string Title {get; set;}
public virtual A AField {get; set;}
public virtual B BField {get; set;}
}
I need update my D object. I use dependency injection so I can use repositories in controller:
A aObj = aService.GetAById(id);
B bObj = bService.GetBByName(name);
D dObj = new D()
{
Title = "MyTitle",
AField = aObj,
BField = bObj
};
dService.Update(dObj);
In each class repository I just create context as private field:
private MyContext db = new MyContext();
and I use it in every method like:
var model = db.A.Where(x=>x.Id == id);
return model;
But it can't work because both classes A and B has field with C class so I still got excepted: An entity object cannot be referenced by multiple instances of IEntityChangeTracker when I call dService.Update(dObj) (second listing).
I found that I should detach context in every method in each repositroy like this:
var model = db.A.Where(x=>x.Id == id);
db.Entry(model).State = System.Data.Entity.EntityState.Detached;
return model;
Exception was gone but now CField in aObj and bObj is always null and dObj.BField is not updated.
How can I fix that and what I'm doing wrong? I lost a few days for finding out what I should do: I even try remove private context field in repositories and in every method just use using(var db = new MyContext()) but then exception "An entity object cannot be referenced by multiple instances of IEntityChangeTracker" is back.
You can't mix entities from different contexts in EF. Use ids instead.
Update models:
class A {
public int Id {get; set;}
public string Name {get; set;}
public int CFieldId {get; set;}
public virtual C CField {get; set;}
}
class B {
public int Id {get; set;}
public string Name {get; set;}
public DateTime Date {get; set;}
public int CFieldId {get; set;}
public virtual C CField {get; set;}
}
class C {
public int Id {get; set;}
public string Name {get; set;}
}
class D {
public int Id {get; set;}
public string Title {get; set;}
public int AFieldId {get; set;}
public int BFieldId {get; set;}
public virtual A AField {get; set;}
public virtual B BField {get; set;}
}
And in controller:
A aObj = aService.GetAById(id);
B bObj = bService.GetBByName(name);
D dObj = new D()
{
Title = "MyTitle",
AFieldId = aObj.Id,
BFieldId = bObj.Id
};
dService.Update(dObj);