ASP.Net Web API 2 Serialized JSON Error: "Self Referencing Loop" - entity-framework-6

Web API Controller calls a stored procedure in an Entity Framework Database-First Model.
The stored procedure inserts an entry into my SQL Server Database and then returns that newly created entry.
The Function Import of the stored procedure is set to return a Complex Type, which is a custom created TagDTO(This DTO is created within TasksModel.tt)
However, I continue to get the error "Self Referencing Loop Detected" when this API method is called.
What am I missing from the below? The stored procedure does insert the data correctly.
TagDTO class:
API Controller code:

Make sure that you remove the object from your db context before returning it. I believe this can be done by adding the following Evict method to your db context. This will make it so that it only serializes the immediate values for that object, it will not attempt to serialize Navigation Properties.
// this goes inside of your Context Object, parent class may already implement it
public void Evict(object entity)
{
Entry(entity).State = EntityState.Detached;
}
then use it like this:
dbContext.Evict(entityFrameworkObject);

Related

ASP.Net Boilerplate get entity after create

I'm using AsyncCrudAppService Create method for creating entity. Call create method from controller, get newly created entity id, then call Get method of AsyncCrudAppService. But returned data don't sets related entities. I'm having this problem only in this scenario, i mean when i call GetAll(), Get() in other scenarios i'm not getting this problem.
The newly created entity is available after you call SaveChanges method of your unit of work.
var record = new Record() { Name = "lorem ipsum" };
_recordRepository.Insert(record);
CurrentUnitOfWork.SaveChanges();
After that, if you put debugger breakpoint and hover record variable - it is already loaded as DB record.

In GORM, Object is not modified in database when the object property is modified at Controller

In my Grails App, I have bootstrapped an object of a domain class as:
def user1 = new Users(userID: 1, name: "John Doe")
user1.save()
In my dashboard controller i have retrieved the object and modified its property name as:
Users userObj = Users.get((Long) 1)
println(userObj as JSON); // This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"John Doe"}
userObj.name = "anonymous"
Now i create a new Users object to retrieve the changed object with same ID 1 as
Users otherUserObj = Users.get((Long) 1) // **Line 2** Is this retrieving from database or from GORM session?
print(otherUserObj as JSON)// This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"anonymous"}
But the value of object in database is not changed. And even when i retrieve the Users object of same id 1 in another controller it gives me the initial object rather than the modified as:
Users userObjAtDifferentController = Users.get(1);
print(userObjAtDifferentController) //This gives me: {"class":"com.prabin.domains.Users","id":1,"name":"John Doe"}
My question is, if the value is not changed in the database, why it gives me the modified object at Line 2 though i have retrieved the object using GORM query (which i guess should retrieve from the database)?
I have also tried using save() after the modification but the result is same.
userObj.save() //doesn't show the changes in database.
My guess is that the object is not being saved to the database because some constraint(s) are invalid. You can determine whether this is the case by replacing your calls to save() with save(failOnError: true). If my guess is correct, an exception will be thrown if saving to the database fails.
When you call the save() method on a domain object, it may not persist in the database immediately. In order to persist the changed value to the database, you would need to do the following.
userObj.save(flush: true)
By using flush, you are telling GORM to persist immediately in the database.
In some cases when validation fails, the data will still not persist in the database. The save() method will fail silently. To catch validation errors as well as save to the database immediately, you would want to do the following
userObj.save(flush:true, failOnError:true)
If validation errors exist, then the GROM will throw ValidationException (http://docs.grails.org/latest/api/grails/validation/ValidationException.html)
You need to consider two things:
If you do save(), it only retains in hibernate session, until you flush it the changes does not persist in database. So, better do save(flush:true, failOnError: true) and put in try/catch block and print exception.
And another important things is, your method in controller needs to be with #Transactional annotation, without it your changes does not persist in database, you will encounter Connection is read-only. Queries leading to data modification are not allowed. exception.
Hope this helps, let me know if your issue is fixed. Happy coding . :)

BreezeJS custom SaveResult containing additional deleted entities

We are parsing the SaveBundle on the server and returning a custom SaveResult. We want to be able to notify the client of additional changed entities as a result of processing the SaveBundle.
For example we have a SaveBundle from the client containing 1 entity to be deleted which when we parse and process on the server we actually delete 2 entities.
As far as we can tell the SaveResult does not contain any properties that would allow us to indicate an entity was 'deleted', rather than say 'modified'.
Is there a way to return additional entity changes through the SaveResult? Or is the only solution to refresh the data by resubmitting a Breeze query client side after the save changes?
I 'think' that if you return the deleted entities with their foreign keys set to null or empty (in the case of non-nullable guids etc.) in the SaveResult then Breeze client-side will detect this and mark them as deleted
I couldn't find anything explicitly in the documentation or the source about this though
here is your answer:
var result = context.SaveChanges(saveBundle);
//create your own EntityInfo object and fill it with the the entity and it's state
var entityInfo = new EntityInfo();
//...
//add it to the result
result.Entities.Add(entityInfo);
//return the result
return result;
Breeze client will then treat that entity like any other entity returned from you normal save proc.
Hope this helps

multiple deserialization of same object should or not create new instances?

In my scenario i've a MVC on iis serializing objects from entity framework where i've overridden GetHashCode and Equal methods since the Id of those objects is immutable once committed to the database.
i also have some client, who can't reach the database, but connect to iis to get those entities serialized via json and deserialize them locally using newtonsoft.json.
When i deserialize them in the clients for a second time, to refresh the data in them, i was expecting the existing instances to be updated automatically.
I'm expecting a little too much?
Should i write some clone method to copy properties and check a cache for existing ids?
Did i wrote something wrong in the Equal and GetHashCode methods?
For instance:
I've a blog entity with a title in the database
The client connect to iis
get a json string containing {"Id" : 1, "Name" : "blogName"}
deserialize it and store it locally
add post to the blog in the same way to an observable collection in the class blog i've used client side
Someone or something Change the blog name in the database
The client try to refresh
get the json string containing {"Id" : 1, "Name" : "newBlogName"}
deserialize it to a new instance of class blog, with same id
What's next? copy the new instance name to the old one, ore there's a better way?
Yes, you expect too much. You can attach new entity (because entity framework context doesn't know about this entity, because you get it from somewhere outside dbcontext) and then save it.
Answer here
//This place is where you can deserialize your entity
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };
using (var context = new BloggingContext())
{
context.Blogs.Attach(existingBlog);
// Do some more work...
context.SaveChanges();
}
I think the best solution is to have two database one server side and one client side, with the same shared entity framework but different connection strings, json.net with the keep object reference setted and use the network only to sync the databases and then query it client side.

how do i execute a stored procedure with vici coolstorage?

I'm building an app around Vici Coolstorage (asp.net version). I have my classes created and mapped to my database tables and can pull a list of all records fine.
I've written a stored procedure where the query jumps across databases that aren't mapped with Coolstorage, however, the fields in the query result map directly to one of my classes. The procedure takes 1 parameter.
so 2 questions here:
how do i execute the stored procedure? i'm doing this
CSParameterCollection collection = new CSParameterCollection();
collection.Add("#id", id);
var result = Vici.CoolStorage.CSDatabase.RunQuery("procedurename", collection);
and getting the exception "Incorrect syntax near 'procedurename'." (i'm guessing this is because it's trying to execute it as text rather than a procedure?)
and also, since the class representing my table is defined as abstract, how do i specify that result should create a list of MyTable objects instead of generic or dynamic or whatever objects? if i try
Vici.CoolStorage.CSDatabase.RunQuery<MyTable>(...)
the compiler yells at me for it being an abstract class.
There's a shortcut in CoolStorage to run a stored procedure. Simply prefix the stored procedure name with "!":
CSDatabase.RunQuery("!procedurename", collection);

Resources