Sharing same Transaction between two Domain models

7 posts, 0 answers
  1. Ertan Deniz
    Ertan Deniz avatar
    8 posts
    Member since:
    May 2010

    Posted 15 Sep 2010 Link to this post

    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 ?
  2. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 16 Sep 2010 Link to this post

    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
  3. DevCraft banner
  4. Ertan Deniz
    Ertan Deniz avatar
    8 posts
    Member since:
    May 2010

    Posted 17 Sep 2010 Link to this post

    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.

  5. Ertan Deniz
    Ertan Deniz avatar
    8 posts
    Member since:
    May 2010

    Posted 17 Sep 2010 Link to this post

    Models use same database.
  6. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 22 Sep 2010 Link to this post

    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
  7. Ertan Deniz
    Ertan Deniz avatar
    8 posts
    Member since:
    May 2010

    Posted 23 Sep 2010 Link to this post

    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....
  8. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 24 Sep 2010 Link to this post

    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
Back to Top
DevCraft banner