I am trying to update an entity but I am getting the following error:
The context is not currently tracking the entity.
My DB table consists of the following fields:
fixturedate, leagueID (FK), Team A (FK), Team B (FK).
My code is as follows:
public void UpdateFixture(Fixture validFixture)
{
Fixture fixture = new Fixture();
fixture = entities.Fixtures.Where(f => f.fixtureId == validFixture.fixtureId).FirstOrDefault();
League league = new League();
league.LeagueId = validFixture.leagueId;
fixture.League = leagueActions.GetLeague(league);
fixture.Team1 = teamActions.GetTeam(validFixture.teamA);
fixture.Team2 = teamActions.GetTeam(validFixture.teamB);
entities.UpdateObject(validFixture);
entities.SaveChanges();
}
When I do entities.AttachTo("Fixtures", validFixture); I get the following error:
The context is already tracking a different entity with the same resource Uri.
What do I need to do to update the fixture entity?
Why the validFixture is not tracked is not clear from your code, however you are selecting a Fixture entity with the same ID as the validFixture instance, which means it is now tracking that entity via the "fixture" instance.
Basically this means that you can update the entity via the "fixture" instance directly. Try just removing the line with the call to the UpdateObject method.
Related
I have two domain classes (simplified) which are related by a Many-to-Many relationship.
A Team can have many Players and a Player can belong to many Teams.
When i call the 'save' action of the Team controller :
A player gets saved in the table. (as expected)
A Team gets saved in the table. (as expected)
When i print team.players and player.teams, i see the correct output (See code below)
Nothing is saved in the relationship table (TEAM_PLAYERS). Why is this happening? Do i need to make entries in the join table myself? If this table is not getting updated, how am i seeing the correct output for point 3. ?
Team.groovy is :
class Team {
static hasMany = [players : Player]
String name;
String size;
}
Player.groovy is :
class Player {
static hasMany = [teams : Team]
static belongsTo = Team
String fullName;
String age;
}
TeamController.groovy is :
class TeamController {
def save() {
def player = new Player(fullName : "John Doe", age : "21").save()
def team = new Team(name : "LocalXI", size : "1").addToPlayers(player).save();
println "The players in the team are : " + team.players
println "The teams this player belongs to are : " + player.teams
}
}
Output for the above (when i call 'save' action ) :
The players in the team are : [John Doe]
The teams this player belongs to are : [LocalXI]
I am new to Grails and Groovy and have spent a lot of time trying to figure this out.
It should work. Take into consideration that the save method is transactional by default and it won't actually persist the data until the method is finished. Within the transaction everything looks correct, that is why the println output is correct.
If you are testing this controller via integration test, your data won't be persisted as the transaction is rolled back automatically for each test.
If you are testing this manually via browser make sure your are not using an in-memory DB in your current runtime environment.
I'm trying to add an object to a database-first ORM EntitySet in an MVC project. I use a piece of code something like this:
public static Boolean CreateListing(string title, string description)
{
ListingEntities ce = new ListingEntities();
ce.Ads.AddObject(new Ad()
{
ID = Guid.NewGuid(),
Title = title,
Description = description,
});
return ce.SaveChanges() == 1;
}
However, the SaveChanges method throws a Data.UpdateException which is thrown by a SqlClient.SqlException. The latter says
"Cannot insert the value NULL into column 'ID', table 'Listings.dbo.Ads'; column does not allow nulls. INSERT fails.
The statement has been terminated."
I wholeheartedly agree. I just don't see why the ID should be null when it seems I set it immediately prior. Any suggestions?
Thanks,
Nathan
Someone else on my team configured the database to create its own ID's, and the issue is resolved.
With a plain connection to SQL Server, you can specify what columns to return in a simple SELECT statement.
With EF:
Dim who = context.Doctors.Find(3) ' Primary key is an integer
The above returns all data that entity has... BUT... I would only like to do what you can with SQL and get only what I need.
Doing this:
Dim who= (From d In contect.Doctors
Where d.Regeneration = 3
Select New Doctor With {.Actor = d.Actor}).Single
Gives me this error:
The entity or complex type XXXXX cannot be constructed in a LINQ to Entities query.
So... How do I return only selected data from only one entity?
Basically, I'm not sure why, but Linq can't create the complex type. It would work if you were creating a anonymous type like (sorry c# code)
var who = (from x in contect.Doctors
where x.Regeneration == 3
select new { Actor = x.Actor }).Single();
you can then go
var doctor = new Doctor() {
Actor = who.Actor
};
but it can't build it as a strongly typed or complex type like you're trying to do with
var who = (from x in contect.Doctors
where x.Regeneration == 3
select new Doctor { Actor = x.Actor }).Single();
also you may want to be careful with the use of single, if there is no doctor with the regeneration number or there are more than one it will throw a exception, singleordefault is safer but it will throw a exception if there is more than one match. First or Firstordefault are much better options First will throw a exception only if none exist and Firstordefault can handle pretty much anything
The best way to do this is by setting the wanted properties in ViewModel "or DTO if you're dealing with upper levels"
Then as your example the ViewModel will be:
public class DoctorViewModel{
public string Actor {get;set;}
// You can add as many properties as you want
}
then the query will be:
var who = (From d In contect.Doctors
Where d.Regeneration = 3
Select New DoctorViewModel {Actor = d.Actor}).Single();
Sorry i wrote the code with C# but i think the idea is clear :)
You can just simply do this:
Dim who= (From d In contect.Doctors
Where d.Regeneration = 3
Select d.Actor).Single
Try this
Dim who = contect.Doctors.SingleOrDefault(Function(d) d.Regeneration = 3).Actor
I have an Employee entity that inherits from a Person entity that inherits from a Resource entity (Employee -> Person -> Resource). Is it possible to programmatically get the EntitySetName of Employee (which should be Resources)?
I take the example from here...
http://msmvps.com/blogs/kevinmcneish/archive/2009/12/03/entity-framework-programmatically-determining-the-entity-set-name-of-an-entity.aspx
... and consider only the else case in the code snippet (so, we have no entity instance with a key):
// I have tested with EF 4.1/DbContext, for EF 4.0 forget this line
var objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
Type entityType = typeof(Employee);
string entityTypeName = entityType.Name;
var container = objectContext.MetadataWorkspace.GetEntityContainer(
objectContext.DefaultContainerName, DataSpace.CSpace);
string entitySetName = (from meta in container.BaseEntitySets
where meta.ElementType.Name == entityTypeName
select meta.Name).First();
string fullEntitySetName = container.Name + "." + entitySetName;
Now the problem is that this code throws an exception in First() because there is no BaseEntitySet with element type name equals "Employee". Obviously because there is only a set for the base type in the model = "Resource".
A possible fix is to change the second and third line above to:
Type entityType = typeof(Employee);
while (entityType.BaseType.Name != "Object")
entityType = entityType.BaseType;
string entityTypeName = entityType.Name;
This should give back "Resources" as the entitySetName IF...
Your entities are not derived from EntityObject (in this case it would probably work if you replace "Object" by "EntityObject" in the while loop above)
Your entities are not derived from another custom type which is not an entity in the model. For example if you have Resource derived from a base type MyBaseObject but didn't include it in the model (there is no DbSet<MyBaseObject> or ObjectSet<MyBaseObject>) then you would have to replace "Object" by "MyBaseObject" in the while loop.
The second limitation is not nice because you could have different non-model base types in your entity classes which would make the code above not very general applicable.
Perhaps there is a smarter way to get the model base type directly from the MetadataWorkspace, but I don't know.
am getting this error on this code (this is an MVC project into which I am trying to integrate Entity Framework):
List<string> consultantSchoolList = new List<string>();
// districts managed by consultant
IQueryable<string> consultClients = rc.consultantDistrictsRepository.districtsForConsultant(userID);
// schools managed by consultant
if (consultClients != null)
{
consultantSchoolList = (from c in rc.clientsRepository.Clients
where (consultClients.Contains(c.cdsCode.Substring(0, 7)))
select c.cdsCode).ToList();
}
on the "consultantSchoolList = " line.
This is an MVC project and I am using a context object that is stored in the HttpContext.Current object. Each repository has a private variable that stores the context object, but each one should point to the same object in the HttpContext.Current Items collection. Would this be considered two different contexts even though they point to the same thing?
Stepping through the code in the debugger shows that the context objects for the two repositories, consultantDistrictsRepository and clientsRepository, do point to the same object in the HttpContext.Current object.
UPDATE Here's how I define the context objects in each repository:
private SchedulerContext context;
public EFConsultantDistricts()
{
context = ContextHelper.GetContext();
}
and GetContext is as follows:
public static SchedulerContext GetContext()
{
if (!HttpContext.Current.Items.Contains("_db_context"))
{
HttpContext.Current.Items.Add("_db_context", new SchedulerContext());
}
return (SchedulerContext)HttpContext.Current.Items["_db_context"];
}
I found the problem -- I was caching the frequently-requested clients list in a Session variable in the Clients repository:
if (HttpContext.Current.Session["clientList"] == null)
{
HttpContext.Current.Session["clientList"] = from c in context.Clients
where (c.Year == fiscalYear)
select c;
}
return (IQueryable<Client>)HttpContext.Current.Session["clientList"];
Since the Session object persists over requests, I guess it was using a previous context object. I thought the client list would be separated from the context object, but I guess not if I'm using IQueryable.
I hate to hit the database every time for this, but I guess I have no choice ... at least for the moment until I get everything straightened out.