How do I avoid a circular reference while serializing Entity Framework class - entity-framework-4

I have an MVC-3 (RC1) application using Entity Framework 4.
I wish to return a JSON object from a controller action. This object is referenced by other objects, which obviously return the reference.
I thus receive the following circular reference error:
Server Error in '/' Application.
A circular reference was detected
while serializing an object of type
'Application.Models.ReferenceObject'.
Description: An unhandled exception
occurred during the execution of the
current web request. Please review the
stack trace for more information about
the error and where it originated in
the code.
Exception Details:
System.InvalidOperationException: A
circular reference was detected while
serializing an object of type
'Application.Models.ReferenceObject'.
NB: Application & ReferenceObject are obviously replacements for the actual namespace / object.
According to Stack Overflow: Circular reference exception when serializing LINQ to SQL classes, this can be overcome using JSON.Net; however I would like to avoid this and instead try to exclude the offending reference properties from the object being serialized.
What do I mean?
I want to do something like this:
IList<ReferenceObject> list = Repository.GetReferenceObjects();
return Json(list.**<method>**("ObjectsReferencingThis"));
where **<method>** is some method that does the opposite to the ObjectQuery(Of T).Include method and ObjectsReferencingThis is the property that is causing the circular reference.
NB: I do not wish to remove these properties or create POCOs as this only affects the Json serialization.
Anyone able to help please?
:)

I had a similar problem when worked on one of my previous project.
Here is what I ended up doing:
IList<Product> list = Repository.GetProducts();
var collection = products.Select(product => new
{
id = product.Id,
name = product.Name,
detailUrl = product.DetailUrl,
imageLargeUrl = product.ThumbNailUrl,
tagtitle = product.Name.ToUpper(),
tagheader = "Words our cherished patrons use to describe this product",
tagwords = from tag in product.Tags group tag by tag.Name into words select new { name = words.Key, weight = words.Count() }
});
var result = new {id = inquiry.Id, products = collection, };
return this.Jsonp(result);
Here is how the result Json would look like:
{
"id" : 2,
"products" : [{
"id" : "3605970008857",
"name" : "TITLE1",
"detailUrl" : "http://www.urlhere.com",
"tagwords" : [{
"name" : "roses",
"weight" : 1
},
{
"name" : "cotton",
"weight" : 1
},
{
"name" : "happy",
"weight" : 1
}]
},
{
"id" : "3605970019891",
"name" : "TITLE2",
"detailUrl" : "http://www.urlhere.com",
"tagwords" : []
}],
}
You can also add any other properties from you referenced objects to the result as you wish,to be shown in your Json object :)

I made a very trivial solution which is not recommended if you have very big list
letters=UserOperations.GetDepartmentLettersForSecretary(pageNumber, pageSize,(Session["User"] as User).DepartmentID.Value, (Session["User"] as User).ID);
foreach (Letter letter in letters)
{
letter.LetterStatus.Letters = null;
}
the problem of circular reference in my case is in LetterStatus.Letters
so I Iterated through the list and assigned it to null
as I told you its not recommended if you have very big list

Related

Retrieving "$ref" field in swagger.json

I am trying to use the swagger parser to parse and retrieve information in the "swagger.json" (io.swagger.parser.SwaggerParser;)
Below is an excerpt of the "swagger.json".
I am trying to retrieve "$ref" : "#/definitions/abc".
"responses" : {
"200" : {
"description" : "abc",
"schema" : {
"$ref" : "#/definitions/abc"
}
},
This is the code to parse it.
SwaggerParser sparse = new SwaggerParser();
Swagger swagger = sparse.read("swagger.json");
// This next line is what I am having a problem with.
swagger.getPath("/endpointurl").getGet().getResponses().get("200").getSchema();
At this point, the ".getSchema()" in the above line has only "getType()" in it I can call. It doesn't have "get$ref()". This is because ".getSchema()" returns a "Property" (io.swagger.models.properties.Property). It doesn't have "get$ref()".
get$ref() is available in "RefProperty" (io.swagger.models.properties.RefProperty)
But ".getSchema()" doesn't return a "RefProperty".
Typecast the result of ".getSchema()" to a "RefProperty" also doesn't work. It ends up in this error.
java.lang.ClassCastException: io.swagger.models.properties.ArrayProperty cannot be cast to io.swagger.models.properties.RefProperty
Has anyone tried parsing a "swagger.json" and was able to retrieve the "$ref": line under "schema" in the "response" block?
Any idea how might I be able to do that?
I figured out a way to do that. Maybe not the best way to do it, but it retrieves the information in "#ref".
Object obj = xxxxx.getSchema(); // xxxxx is whatever your code that gives you ".getSchema()". Mine is in a map and I don't want to distract people.
ArrayProperty arrProp = new ArrayProperty();
arrProp = (ArrayProperty)obj; // .getSchema() returns an ArrayProperty
RefProperty refProperty = (RefProperty) arrProp.getItems(); // .getItems() will return the RefProperty type you need to call ".get$ref()".
String refStr = refProperty.get$ref(); // Voila, there's your content in "#ref".
String simpleRefStr = refProperty.getSimpleRef();
I had to do a few type castings. If you have a more elegant way of doing this, please post here.

Neo4j and json creating multiple nodes with multiple params

I tried many things but of no use.
I have already raised a question on stackoverflow earlier but I am still facing the same issue.
Here is the link to old stackoverflow question
creating multiple nodes with properties in json in neo4j
Let me try out explaining with a small example
This is the query I want to execute
{
"params" : {
"props" : [
{
"LocalAsNumber" : 0,
"NodeDescription" : "10TiMOS-B-4.0.R2 ",
"NodeId" : "10.227.28.95",
"NodeName" : "BLR_WAO_SARF7"
}
]
},
"query" : "MATCH (n:Router) where n.NodeId = {props}.NodeId RETURN n"}
For simplicity I have added only 1 props array otherwise there are around 5000 props. Now I want to execute the query above but it fails.
I tried using (props.NodeId}, {props[NodeID]} but everything fails.
Is it possbile to access a individual property in neo4j?
My prog is in c++ and I am using jsoncpp and curl to fire my queries.
If you do {props}.nodeId in the query then the props parameter must be a map, but you pass in an array. Do
"props" : {
"LocalAsNumber" : 0,
"NodeDescription" : "10TiMOS-B-4.0.R2 ",
"NodeId" : "10.227.28.95",
"NodeName" : "BLR_WAO_SARF7"
}
You can use an array of maps for parameter either with a simple CREATE statement.
CREATE ({props})
or if you loop through the array to access the individual maps
FOREACH (prop IN {props} |
MERGE (i:Interface {nodeId:prop.nodeId})
ON CREATE SET i = prop
)
Does this query string work for you?
"MATCH (n:Router) RETURN [p IN {props} WHERE n.NodeId = p.NodeId | n];"

Update field of embedded documents on multiple Mongoid documents [duplicate]

This question already has answers here:
How to Update Multiple Array Elements in mongodb
(16 answers)
Closed 5 years ago.
I recently started using MongoDB and I have a question regarding updating arrays in a document.
I got structure like this:
{
"_id" : ObjectId(),
"post" : "",
"comments" : [
{
"user" : "test",
"avatar" : "/static/avatars/asd.jpg",
"text" : "....."
}
{
"user" : "test",
"avatar" : "/static/avatars/asd.jpg",
"text" : "....."
}
{
"user" : "test",
"avatar" : "/static/avatars/asd.jpg",
"text" : "....."
}
...
]
}
I'm trying to execute the following query:
update({"comments.user":"test"},{$set:{"comments.$.avatar": "new_avatar.jpg"}},false,true)
The problem is that it update all documents, but it update only the first array element in every document. Is there any way to update all array elements or I should try to do it manually?
Thanks.
You cannot modify multiple array elements in a single update operation. Thus, you'll have to repeat the update in order to migrate documents which need multiple array elements to be modified. You can do this by iterating through each document in the collection, repeatedly applying an update with $elemMatch until the document has all of its relevant comments replaced, e.g.:
db.collection.find().forEach( function(doc) {
do {
db.collection.update({_id: doc._id,
comments:{$elemMatch:{user:"test",
avatar:{$ne:"new_avatar.jpg"}}}},
{$set:{"comments.$.avatar":"new_avatar.jpg"}});
} while (db.getPrevError().n != 0);
})
Note that if efficiency of this operation is a requirement for your application, you should normalize your schema such that the location of the user's avatar is stored in a single document, rather than in every comment.
One solution could be creating a function to be used with a forEach and evaling it (so it runs quickly). Assuming your collection is "article", you could run the following:
var runUpdate = function(){
db.article.find({"comments.user":"test").forEach( function(article) {
for(var i in article.comments){
article.comments[i].avatar = 'new_avatar.jpg';
}
db.article.save(article);
});
};
db.eval(runUpdate);
If you know the indexes you want to update you can do this with no problems like this:
var update = { $set: {} };
for (var i = 0; i < indexesToUpdate.length; ++i) {
update.$set[`comments.${indexesToUpdate[i]}. avatar`] = "new_avatar.jpg";
}
Comments.update({ "comments.user":"test" }, update, function(error) {
// ...
});
be aware that must of the IDE's will not accept the syntax but you can ignore it.
It seems like you can do this:
db.yourCollection.update({"comments.user":"test"},{$set:{"comments.0.avatar": "new_avatar.jpg", "comments.1.avatar": "new_avatar.jpg", etc...})
So if you have a small known number of array elements, this might be a little easier to do. If you want something like "comments.*.avatar" - not sure how to do that. It is probably not that good that you have so much data duplication tho..

SAPUI5 - complex model binding

I have this json model:
model/data.json
{
"orders" : [
{
"header" : { "id" : "00001", "description" : "This is the first order" },
"items" : [
{ "name" : "Red Book","id" : "XXYYZZ" },
{ "name" : "Yellow Book", "id" : "AACCXX" },
{ "name" : "Black Book", "id" : "UUEEAA" },
]
},
{
// another order with header + items
},
.....
]
}
and I'm assigning it onInit to the view, like this:
var model = new sap.ui.model.json.JSONModel("model/data.json");
sap.ui.getCore().setModel(reqModel);
I'm trying to display a list of orders in the first view (showing the id), like this:
var list = new sap.m.List({
id: "mainList",
items: []
});
var items = new sap.m.ActionListItem({
text : "{id}",
press : [ //click handler, onclick load the order details page ]
});
list.bindItems("/orders", items);
.... // add list to the page etc etc
What I cannot do, is connect each order to its header->id.. I tried
text: "/header/{id}"
text: "{/header/id}"
in the items declaration, and
list.bindItems("/orders/header", items)
in the list binding, but none of them works.. The id value is not displayed, even though a "blank" list item is shown..
Any idea? What am I doing wrong?
Thank you
The solution was one of those I tried (but I don't know why it didn't work at that time)
text: "{/header/id}"
The ListItem acts as a Template for a list/array of objects. That's why you bind it against an array structure in your data:
list.bindItems("/orders", itemTemplate)
That makes bindings of the ListItem relative to /orders and therefore your item should look like this without leading '/' (absolute paths would look like this /orders/0/header/id asf.):
var itemTemplate = new sap.m.ActionListItem({
text : "{header/id}",
press : [ //click handler, onclick load the order details page ]
});
Not quite sure how you made it work the way you have shown... May be it's not as picky as I thought.
Btw: For whatever reason the ResourceModel builds an exception of that syntax. You can always omit the leading '/' when dealing with ResourceModels (probably because they do not allow nested structures).
BR
Chris
Cannot add comments yet, therefore an answer to you solved Problem, that could answer the initial problem. (And inform People using that example in any way)
In the current code listing you use the variable "reqModel" to set the model, but the variable with the model in it is named "model" in the line before. Maybe that was the first reason why both of your examles would not work?
Perhaps this error was cleared on rewriting some passages while testing.
greetings! -nx

Breeze.js OData - Complex Type fails --> Cannot call method '_createInstanceCore' of null

We are currently developing a small Hmtl/ JavaScript application with breeze.js (Version 1.3.4). We configured to used OData protocol to query the entities.
With a simple entity it just works fine. If we are querying a complex entity (contact entity with two complex type properties for phone numbers and addresses), we receive the following error:
"TypeError: Cannot call method '_createInstanceCore' of null
at ctor.startTracking (<ServerAddress>/scripts/breeze.debug.js:14086:49)
at Array.forEach (native)
at ctor.startTracking (<ServerAddress>1/scripts/breeze.debug.js:14069:12)
at new ctor <ServerAddress>/scripts/breeze.debug.js:2952:52)
at proto._createEntityCore (<ServerAddress>1/scripts/breeze.debug.js:6478:9)
at mergeEntity <ServerAddress>/scripts/breeze.debug.js:12458:39)
at processMeta (<ServerAddress>/scripts/breeze.debug.js:12381:24)
at visitAndMerge (<ServerAddress>/scripts/breeze.debug.js:12361:16)
at <ServerAddress>/scripts/breeze.debug.js:12316:33
at Array.map (native)
From previous event:
at executeQueryCore (<ServerAddress>/scripts/breeze.debug.js:12290:77)
at proto.executeQuery (<ServerAddress>/scripts/breeze.debug.js:11243:23)
at DataContext.executeCachedQuery (<ServerAddress>/App/services/datacontext.js:138:33)
at DataContext.getContactsBySearchParams (<ServerAddress>/App/services/datacontext.js:111:25)
at Search.searchCmd.ko.asyncCommand.execute (<ServerAddress>/App/viewmodels/search.js:34:38)
at Search.ko.asyncCommand.self.execute (<ServerAddress>/scripts/knockout.command.js:57:29)
at HTMLButtonElement.ko.bindingHandlers.event.init (<ServerAddress>/scripts/knockout-2.2.1.debug.js:2318:66)"
While debugging the code, we see, that the dataType field of the complex property instance is null:
val = prop.dataType._createInstanceCore(entity, prop.name);
We can also see that the complexTypeName has a strange value formatting like:
<ComplexTypeName>):#<NameSpace>
Another thing we noticed concerning the strange complex type name is, that the entities property is a collection of complex types (a contact may have multiple addresses). The check on Line 14085 always returns isScalar = true, but a complex array should be created instead.
Is there a problem with the OData Metadata for complex types? How could we solve this issue?
Thank you in advance for your answer.
Cheers,
Marc
Breeze currently does support both scalar complex types and arrays of complex types.
But there is a bug with using EntityManager.createEntity to create an entity and its complex type values in a single pass. This will be fixed in the next release in about a week.
So for now the following does NOT work. ( Assume 'location' in the examples below is a complex property of type 'Location', itself with several other properties)
var supplier = em.createEntity("Supplier",
{ companyName: "XXX", location: { city: "LA" } }
);
but the following will ( assuming you are using the breeze Angular/backingStore impl - the knockout code would look a bit different)
var supplier = em.createEntity("Supplier", { companyName: "XXX" });
supplier.location.city = "San Francisco";
supplier.location.postalCode = "91333";
or the following
var supplier = em.createEntity("Supplier", { companyName: "XXX" });
var locationType = em.metadataStore.getEntityType("Location");
supplier.location = locationType.createInstance(
{ city: "Boston", postalCode: "12345" }
);
I am seeing the same problem with breeze 1.4.5.
My metadata looks like:
{ "shortName":"Phone",
...
"dataProperties":[ {"name":"phoneNumber",
"complexTypeName":"PhoneNumber#mynamespace",
"isScalar":true }]
...
},
{"shortName":"PhoneNumber",
"namespace":"mynamespace",
"isComplexType":true,
"dataProperties":[ ... ]
}
My client code makes a call:
var newPhone = manager.createEntity('Phone', {phoneNumber:{num: "234-2342"}});
(there are more properties in the PhoneNumber complex type, but you yet the picture).
The breeze code (same call stack as orignal poster's) tries to dereference the dataType field, which is not defined, and throws an exception:
if (prop.isDataProperty) {
if (prop.isComplexProperty) {
if (prop.isScalar) {
val = prop.dataType._createInstanceCore(entity, prop);
} else {
val = breeze.makeComplexArray([], entity, prop);
}
I went through the Zza sample's schema and found no examples of complex data properties. The Northwind schema included with the samples bundle does, but I'm not sure how to get it to work with my schema.

Resources