ASP.Net Boilerplate get entity after create - asp.net-mvc

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.

Related

ASP.Net Web API 2 Serialized JSON Error: "Self Referencing Loop"

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);

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 . :)

entity gets detached somehow between ui-router resolve and the controller

I'm trying to reject changes on a newly added entity (expecting breeze to set entityState to detached). Most times it works, but once in a while (mostly after I have already performed an entity create and reject), the rejectChanges call will fail because there is a null reference to the entityAspect.entityManager property.
I am getting my entity instance through "resolve" of ui-router on abstract parent state. Then in the abstract parent controller, I assign that instance to $scope. From then on I deal with $scope.myEntity instead of the resolved variable in my constructor. When I call entity This is my resolve function:
resolve:{
myEntity:function(sharedEntityManager,$stateParams, $q){
return $q.when(sharedEntityManager.getMyEntity($stateParams.entityId))
.then(function(myEntity){
if(!myEntity && myEntity.entityAspect.entityState.isDetached()){
$q.reject();
}
else
{
return myEntity;
}
});
}
}
Then in my parent abstract controller, I call this:
$scope.myEntity = myEntity;
The error I get showing null entityManager...
TypeError: Cannot read property 'isRejectingChanges' of null
at __using (breeze.debug.js:449)
at EntityAspect.proto.rejectChanges (breeze.debug.js:3687)
The error seems to occur only after I have successfully done 1 cycle of creating entity, rejecting that entity. Then when I create another new entity, that new entity somehow goes from "Added" and having an entityManager, to "Detached" and null entityManager. I confirmed that in the resolve function, entityState is "Added", but in the controller constructor, the injected entity from ui-router is now "Detached".
Anyone familiar with this behavior and is there a work around?
Are you sure about the test in the then function? It seems off to me. Do you really mean if(!myEntity && ... or should it be if(!myEntity || ...)

Entity Framework: I don't understand the purpose of EntityCollection.Attach and EntityReference.Attach

ObjectContext.Attach and ObjectSet.Attach are used to attach a detached entity ( which already exists in a DB ) to a context – this way when ObjectContext.SaveChanges is called, EF doesn't try to send an insert command for this attached entity
But I don't understand the purpose of EntityCollection.Attach and EntityReference.Attach. Namely, the two methods can only attach entities that are already managed by ObjectContext ( thus they can't be used to attach entities with EntityState set to Added or Detached ).
And since entities managed by ObjectContext already have their relationships automatically resolved ( ie their EntityReference property returns a parent entity and their EntityCollection property contains related child entities ), I fail to understand what exactly would we gain by using EntityCollection.Attach or EntityReference.Attach to attach a related entity E1 to a particular entity E2, since E1 was already attached to E2 automatically by ObjectContext?
Thank you
As an example, if you have a customer in the ObjectContext and you want to get that
customer’s reservations, you could call the following:
myCust.Reservations.Load()
This would load all of the reservations for that customer.
However, if you want to filter those reservations, you can use CreateSourceQuery in-
stead, as shown in the following code:
var customer=context.Contacts.OfType<Customer>().First();
var sourceQuery = customer.Reservations.CreateSourceQuery()
.Where(r => r.ReservationDate > new DateTime(2008, 1, 1));
customer.Reservations.Attach(sourceQuery);
The query will execute when the Attach method is called. Now only the subset of reservations for that customer will be retrieved from the database and materialized as
objects.
You can also use CreateSourceQuery to filter on types. In the following code, Attach is
being used with an EntityReference, which will not take IQueryable. Instead, you need
to pass in an object, which you can get using the FirstOrDefault query method. Since
Attach will throw an exception if you attempt to pass in a null, you need to test for null
before calling Attach:
var addresses = context.Addresses.Take(5);
foreach (var a in addresses)
{
var sq = a.ContactReference.CreateSourceQuery()
.OfType<Customer>().FirstOrDefault();
if (sq != null)
a.ContactReference.Attach(sq);
}
With this code, only customers will be loaded.

Cannot insert new Employee entity using InsertOnSubmit()

I'm facing this exception An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported. when I try to insert a new entity into my Employees table (the master one).
There is a relationship between the master Employees table and the details Orders table, and I'm sure that the relationship between these two tables (and specifically Employee.Orders EntitySet) is the cause of the problem since when I removed the relationship, it returns back to insert into Employees table with no problems.
When I searched for the problem, there was this blog post which I tried to implement but my case is a different than the one in the blog post in these items:
He faces the exception when tries to update (while I try to insert).
The tables architecture is different.
how can I solve this problem?
Here's the insertion code:
Employee emp = new Employee();
emp.Name = empName; // empName is a local variable
// What should I default emp.Orders to?
dc.Employees.InsertOnSubmit(emp);
dc.SubmitChanges();
P.S: My DataContext is defined on class-level in my repository and the exception is being thrown when I call dc.SubmitChanges();. and I didn't Attach any object why does it say that?
Here is an article explaining what you need to do using the Attach and Detach methods:
http://www.codeproject.com/KB/linq/linq-to-sql-detach.aspx
I am guessing it is trying to save something else besides just the employee object or you aren't showing us the full code in your repository. When you instantiate your DataContext object (dc) try setting DeferredLoadingEnabled = false, and ObjectTrackingEnabled = false and see if it works. If it does, try watching the SQL code in SQL Server Profiler and see if it is modifying other objects that may have came from a different context like the message says.
var dc = new MyDataContext()
{
DeferredLoadingEnabled = false,
ObjectTrackingEnabled = false
};
My bet is on the primary key.
Are you sure the primary key is also set on auto increment?
Did you
try changing the name, does it work then?
What happens if you remove
all rows from your DB? can you insert one then?

Resources