1

My project is divided to PresentationLayer, BusinesLogicLayer and DataAccessLayer. Every created object goes through these layers. In simplifying:

SetFilter.xaml.cs

FilterFactory fFactory = new FilterFactory();
Filter myFilter = fFactory.Create(someClient, time, message);
FilterBLO filterBLO = new FilterBLO();
filterBLO.Save(myFilter);

FilterBLO.cs

FilterDAO filterDAO = new FilterDAO();
using (TransactionScope transcope = new TransactionScope())
{
    filterDAO.Save(myFilter);
    transcope.Complete()
}

FilterDAO.cs

using(DBDataContext dbdc = new DBDataContext)
{
    dbdc.Filter.InsertOnSubmit(myFilter);
    changeSet = dbdc.GetChangeSet();
    dbdc.SubmitChanges()
}

Filter is connected with table Client using ClientFilter table containing FilterID and ClientID. (many-to-many relationship)

If I create new 3 objects everything's ok, but if I'm getting existing Client in database (also using ClientBLO and ClientDAO so in separate TransactionScope and separate DBDataContext) I get error:

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.

(I searched other similar threads but I didn't found solution to my problem.)

And finally my question

How should I save myFilter if Client exists in database. I tried Attach() it to datacontext in FilterDAO.cs but I get the same error.

Saint
  • 5,397
  • 22
  • 63
  • 107

1 Answers1

3

You have to obtain Client from the database with the same DataContext you use to InsertOnSubmit the Filter; then you have to set Client value in the Filter object with that object before InsertOnSubmit.

Andrea Colleoni
  • 5,919
  • 3
  • 30
  • 49
  • I know that's because of another DataContext, but I don't have a good idea how to make it in my structure. And maybe there's some other solution than global DataContext (because I think such a division is better solution, isn't it?) – Saint Nov 08 '11 at 14:11
  • 1
    It should in non transactional scenario. How about passing the DataContext to the DAL and crating a new one if the one passed is null? – Andrea Colleoni Nov 08 '11 at 14:17
  • What do you mean? Do you propose, return DataContext from ClientDAL to PresentationLayer and pass it again to FilterDAL? It is kinf of solution, but I'm not sure how to the correctness such an action from the perspective of sql and linq – Saint Nov 08 '11 at 14:27
  • I think you'd better to rely on obtaining the DataContextfrom a factory; get it in the PresentationLayer (where the transactional logic begins and ends) and pass it to all your xxDAO classes. All xxxDAO classes should then accept a DataContext argument and if null call the same factory you use in the presentation layer. – Andrea Colleoni Nov 08 '11 at 15:57