This is a migrated thread and some comments may be shown as answers.

Sharing same Transaction between two Domain models

6 Answers 124 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Ertan Deniz
Top achievements
Rank 1
Ertan Deniz asked on 15 Sep 2010, 08:14 AM
How can we achieve this ? or Is it possible ?

If we model our objects in two or more domains (models), how can we save our objects in the same transaction ?

6 Answers, 1 is accepted

Sort by
0
Alexander
Telerik team
answered on 16 Sep 2010, 03:33 PM
Hi Ertan Deniz,

I think this would not be very easy, if possible at all. Can you please give a bit more details on your scenario - do the models work with the same database or with different ones? Also, by transaction do you mean an OpenAccess transaction (which is just a logical transaction) or the physical transaction opened on the server?

Regards,
Alexander
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Ertan Deniz
Top achievements
Rank 1
answered on 17 Sep 2010, 09:53 AM
It is a OpenAccess transaction. I have a plan to use Model.SaveChanges().

Let's say I' ve decomposed my application into two subdomains. 
ModelA has five 5 or more Objects (Order System with Customer,Product,Order,OrderDetails etc)
ModelB has five or more objects (Financial System with Accounting, AccountingTransactions etc)

I have a process. I want to work with the objects (Save,Delete) in two domains..

If I Save ModelA then the current transaction will be saved and closed.

I can not add all objects into same model. This leads me into one model with all objects.
May be, I may add some objects into related models. In this case, I can save in the same transaction (SaveChanges)..

This is the my case. Please give a clear explanation on working with different models in OpenAccess.

0
Ertan Deniz
Top achievements
Rank 1
answered on 17 Sep 2010, 10:00 AM
Models use same database.
0
Alexander
Telerik team
answered on 22 Sep 2010, 04:54 PM
Hi Ertan Deniz,

This should be possible as you are using the same database in both models. To achieve that you will have to merge the metadata from the two models in memory, before obtaining a database connection. This way you will be able to work with all classes within a single context instance, calling SaveChanges() only once. You can read some more details on why the metadata should be merged in the last post of this forum thread. There is also mentioned how to gather the metadata dynamically from many application modules.

If you however, do not need to use modules and know that you will be always using a constant number of domain models (two at the moment), you can directly use code like this:
XmlMetadataSource source1 = XmlMetadataSource.FromAssemblyResource(typeof(Product).Assembly, "EntityDiagrams1.rlinq");
MetadataContainer container1 = source1.GetModel();
 
XmlMetadataSource source2 = XmlMetadataSource.FromAssemblyResource(typeof(Customer).Assembly, "EntityDiagrams2.rlinq");
MetadataContainer container2 = source2.GetModel();
 
MetadataContainer mergedMetadata = GetMergedMetadata(container1, container2);
 
//initialize the database with the metadata merged from the two models
Database.Get("NorthwindEntityDiagrams", new BackendConfiguration() { Backend = "mssql" }, mergedMetadata);
 
//instantiate a context; It does not matter which model the context belongs to.
Model1.NorthwindEntityDiagrams context = new Model1.NorthwindEntityDiagrams();
 
context.GetAll<Customer>().First().ContactName += "NewContactName";
context.GetAll<Product>().First().ProductName += "NewProductName";
 
context.SaveChanges();

The Database.Get() call should be made only once, before instantiating any context. Afterwards you can create and dispose unlimited count of contexts. As you can see, the Customer and Product classes belong to different models but are managed by one context.
Here are the helper methods that you will need:
static MetadataContainer GetMergedMetadata(MetadataContainer container1, MetadataContainer container2)
{
    MetadataContainer metadata = new MetadataContainer();
 
    MergeMetaItems(metadata.PersistentTypes, container1.PersistentTypes, container2.PersistentTypes);
    MergeMetaItems(metadata.Tables, container1.Tables, container2.Tables);
    MergeMetaItems(metadata.Views, container1.Views, container2.Views);
    MergeMetaItems(metadata.StoredProcedures, container1.StoredProcedures, container2.StoredProcedures);
    MergeMetaItems(metadata.Constraints, container1.Constraints, container2.Constraints);
    MergeMetaItems(metadata.Indexes, container1.Indexes, container2.Indexes);
 
    return metadata;
}
 
static void MergeMetaItems(IList destinationCollection, IEnumerable source1, IEnumerable source2)
{
    foreach (MetaItem item in source1)
    {
        destinationCollection.Add(item);
    }
    foreach (MetaItem item in source2)
    {
        if (!ContainsMetaItem(destinationCollection, item))
        {
            destinationCollection.Add(item);
        }
    }
}
 
static bool ContainsMetaItem(IList collection, MetaItem metaItem)
{
    foreach (MetaItem item in collection)
    {
        if (item.Name.Equals(metaItem.Name))
        {
            return true;
        }
    }
    return false;
}

Hope that helps. Please contact us back if you need further assistance.

Best wishes,
Alexander
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Ertan Deniz
Top achievements
Rank 1
answered on 23 Sep 2010, 07:08 AM
Thanks for the way to a solution.

But there must be simpler way to accomplish this requirement.

Can you set a relation between models at the beginning in constructing the other models ? In this way, you can share transactions and metadata etc..

If you call SaveChanges with second model, two models can saved in the same transaction....

Is it possible ? May be in the next version....
0
Alexander
Telerik team
answered on 24 Sep 2010, 04:30 PM
Hello Ertan Deniz,

I am afraid that this is the only solution at the moment. Out plans for making the usage of multiple models easier are to do the metadata merging automatically or at least provide an API for this. However, this will still not allow having references between the models.

Regards,
Alexander
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
Development (API, general questions)
Asked by
Ertan Deniz
Top achievements
Rank 1
Answers by
Alexander
Telerik team
Ertan Deniz
Top achievements
Rank 1
Share this question
or