0

I am using EF4 and trying to use POCOs and be persistent ignorant all the way through. This works ok, except for associations.

For a simple example, I have countries and countries have an associated currency. Each Country has an association (FK) which is a Currency object setup as a property, i.e.:

  public class Currency
  {
    //three-character currency-code
    public virtual string Id { get; set; }
    public virtual string Name { get; set; }
    //There are other primitive properties, but they're not important
  }

  public class Country
  {
    //two-character country-code
    public virtual string Id { get; set; }
    public virtual string Name { get; set; }
    //There are other primitive properties, but they're not important

    //Fixup not shown
    public virtual Currency Currency { get; set;}
  }

I create a new country via a POCO (auto-generated from MS POCO tt):

  var currency = currencyRepository.Find("AAA");  //returns POCO for the 'AAA' currency
  var country = new Country { Id = "AA", Name = "AA Test", Currency = currency};

I'm using a UnitOfWork pattern to implement the database changes, along the lines of:

  public void RegisterNew(country)
  {
    MyDbContext.Countries.AddObject(country);
  }

However, when I call SaveChanges, EF returns that I can't create the Country, because the associated Currency already exists (fails on inserting the Currency, PK violation).

Well, ok, but I want to associate the Country with the existing Currency... that's why I gave it the currency.

I could add code in RegisterNew to Attach the existing Currency object, however, I want a generic solution. I don't want to have to write specific code for each POCO object I want to persist that attaches existing associations.

Is there some way of telling EF that if the associated entity already exists, then use it (if the POCO entity didn't match the persistent entity, then it could throw an error)?

I'm assuming not. Without being able to do this, I'm going to have to write a lot of (to me) pointless extra code to say 'yes, this is an existing association, obviously, use the existing persisted entity) and, more annoyingly, I won't be able to write generic code to add any kind of POCO object, which is not DRY and a lot of pointless effort, from my perspective.

Perhaps I could use foreign keys instead, but then I wouldn't have the associations and it wouldn't be a persistence-agnostic ORM solution, but a rather heavy persistence-aware DAL.

nicodemus13
  • 2,258
  • 2
  • 19
  • 31
  • Did you load currency from the same context used to save country? – Ladislav Mrnka May 17 '11 at 11:47
  • Hi @Ladislav, thanks, I've been reading some of your posts and http://www.ladislavmrnka.com/. Perhaps I'm taking the wrong approach, but personally, I only want to be interested in persistence at the persistence level. My point is that I don't want to have to load my country from the context manually, as I'll have to write a load of boilerplate code for any class that has associations... – nicodemus13 May 17 '11 at 13:35
  • You don't need to load it "manually". I'm just asking if your if your `currencyRepository.Find` used the same context instance as `RegisterNew`? – Ladislav Mrnka May 17 '11 at 13:47
  • Ok, then no, they are different contexts. I have the repository (access) and uow (update) separate. I want to send POCOs to my UoW and not have to care about their related associations. – nicodemus13 May 17 '11 at 14:03
  • In such case you are doomed. No way to do this unless you detach entity from the first context and attach it to the new one which is far away from persistence ignorance. It should work if your repository and UoW shares the context. – Ladislav Mrnka May 17 '11 at 14:11
  • Thanks Ladislav, I'll continue thinking about it, it seems I can't follow the design I want. – nicodemus13 May 17 '11 at 14:14
  • When thinking about this I also recommend you reading this: http://stackoverflow.com/questions/3635071/update-relationships-when-saving-changes-of-ef4-poco-objects/3635326#3635326 Just in case you start to play with detached entities. – Ladislav Mrnka May 17 '11 at 14:15

1 Answers1

1

Try setting the primitive value for the currency id in the Country rather than Currency object. I encountered a similar problem and this solution works for me!

Spencer
  • 11
  • 1