views:

163

answers:

2

I have 3 entities

  • Printer
  • Server
  • Driver

The Printer has Server and Driver properties

Somwhere in my code I've set up an IEnumerable<Printer> where each instance of printer holds it's own Server and Driver entities.

Now when I'm trying to submit it to the db, I'm using following code:

foreach (Printer p in printers)
  {
   printmanEntities _dc = new printmanEntities();
   p.Driver = _dc.DriverSet.FirstOrDefault(d => d.Name == p.Driver.Name) ?? p.Driver;
   p.Server = _dc.ServerSet.FirstOrDefault(s => s.Name == p.Server.Name) ?? p.Server;

   _dc.AddToPrinterSet(p);

   _dc.SaveChanges();  
   }

It is supposed that I'll get a record for each Printer object, and a single record for each unique Driver and Server name. But actual result is quite wired.

Code above produces a single record for each unique Driver object, but for no obvious reason creates more than one record for each unique Server. And all Printer records point to single Server record.

Furthermore if I assign p.Server first, then I get only unique records for server entities but multiple records for Driver entities.

What am I doing wrong?

Update: Replaced EF with LINQ2SQL and it worked just as i expected. A single row for each unique entity, nothing more.

A: 

This suggests that dc.ServerSet.FirstOrDefault(s => s.Name == p.Server.Name) is returning null, but the Driver call returns a record. Why? I don't know. Look at SQL Profiler and see what comes back from the DB server. It would explain your results, though.

Update: I think I may have figured out what is going on here. Try and change your code as follows. If it works, I'll explain the reasoning.

printmanEntities _dc = new printmanEntities();
_dc.AddToPrinterSet(p);

p.Driver = _dc.DriverSet.FirstOrDefault(d => d.Name == p.Driver.Name) ?? p.Driver;
p.Server = _dc.ServerSet.FirstOrDefault(s => s.Name == p.Server.Name) ?? p.Server;

_dc.SaveChanges();

Note that the only thing I did here was change the order of operations.

Craig Stuntz
As wired as it sounds it does return a proper value, and all Printers in db table are linked to proper Server.I guess i just found a wired bug.
Alexander Taran
Something else is going on then. I can't say what from the example, but I've never seen the Entity Framework do this sort of thing incorrectly.
Craig Stuntz
Try this updated code.
Craig Stuntz
A: 

Oddly enough, DataContainer does not return entities that you attached to graph but didn't commit to db as a query result. So you can't get entity you added, but not permited with Select(). )-:

Alexander Taran