0
1

so, I like Linq2Sql behavior very much and it looks really convinient to me. See the difference with between clientprofile and linq2sq

1 linq2sql:

using (var ts = new TransactionScope())
{
    using (var db = new DataClasses1DataContext())
    {
        var e = new MyEntity() { Id = 123, Text = "qweqweqweqwe" };
        db.MyEntities.InsertOnSubmit(e);

        db.SubmitChanges();

        Assert.That(db.MyEntities.Count(), Is.EqualTo(1)); // TADA! This passes
    }

    ts.Complete();
}

2: DO4.4

var config = DomainConfiguration.Load("Default");
var domain = Domain.Build(config);
var scfg = new SessionConfiguration()
               {
                   Options = SessionOptions.ClientProfile
               };

using (var session = domain.OpenSession(scfg))
{
    using (var transactionScope = session.OpenTransaction())
    {
        // Creating new persistent object
        var helloWorld = new MyEntity(session)
        {
            Text = "Hello World!"
        };

        foreach (var myEntity in session.Query.All<MyEntity>())
        {
            Console.WriteLine(myEntity.Text); // no entities :(((
        }

        // Committing transaction
        transactionScope.Complete();
    }

    using (var transactionScope = session.OpenTransaction())
    {
        foreach (var myEntity in session.Query.All<MyEntity>())
        {
            Console.WriteLine(myEntity.Text); // no entities :((( i've completed the transaction(!)
        }

        transactionScope.Complete();
    }

    session.SaveChanges();
}

// Reading all persisted objects from another Session
using (var session = domain.OpenSession())
{
    using (var transactionScope = session.OpenTransaction())
    {
        foreach (var myEntity in session.Query.All<MyEntity>())
        {
            Console.WriteLine(myEntity.Text); // here we go...
        }

        transactionScope.Complete();
    }
}

And this is really frustrating, that I cant access my newly created entity via standard methods.

asked Mar 16 '11 at 10:30

xumix's gravatar image

xumix
425757682

edited Mar 16 '11 at 10:31


One Answer:

Hello xumix,

You said, you like LINQ2SQL behavior, so why don't you follow it in all respects? Give a try to this piece of a cake:

var config = DomainConfiguration.Load("Default");
var domain = Domain.Build(config);
var scfg = new SessionConfiguration()
           {
               Options = SessionOptions.ClientProfile
           };

using (var session = domain.OpenSession(scfg))
{
    // Creating new persistent object
    var helloWorld = new MyEntity(session)
    {
        Text = "Hello World!"
    };
    session.SaveChanges();
    Assert.IsTrue(session.Query.All<MyEntity>().Any(a => a.Text == "Hello World!"));
}

answered Mar 16 '11 at 10:38

Dmitri%20Maximov's gravatar image

Dmitri Maximov
22111211

See the transaction above. Ok:

using (var session = domain.OpenSession(scfg))
{
    using (var transactionScope = session.OpenTransaction())
    {
        var helloWorld = new MyEntity(session)
        {
            Text = "Hello World!"
        };

        session.SaveChanges(); // BOOM! InvalidOperationException

        foreach (var myEntity in session.Query.All<MyEntity>())
        {
            Console.WriteLine(myEntity.Text);
        }

        transactionScope.Complete();
    }
}
(Mar 16 '11 at 10:52) xumix xumix's gravatar image

In ClientProfile such transactions are local (in-memory), so unless you call Session.SaveChanges() which in turn will lead to persist, you won't be able to see newly added/modified entities in query result.

That's why I'd recommend you to truly follow LINQ2SQL pattern (get rid of transactions), or call Session.SaveChanges() before querying for entities.

(Mar 16 '11 at 10:57) Dmitri Maximov Dmitri%20Maximov's gravatar image

Hm, I used transactions in linq2sql and had no problems. So why can't I use them now?

(Mar 16 '11 at 11:01) xumix xumix's gravatar image

It seems i should use sessions instead of transactions in this scenario

(Mar 16 '11 at 11:03) xumix xumix's gravatar image

You may use, the only thing you shouldn't forget is to call Session.SaveChanges() in ClientProfile, it is an analogue to db.SubmitChanges() call in linq2sql.

(Mar 16 '11 at 11:06) Dmitri Maximov Dmitri%20Maximov's gravatar image

Nope.This fails.

using (var session = domain.OpenSession(scfg))
{
    using (var ss = domain.OpenSession(scfg))
    {
        var helloWorld = new MyEntity { Text = "Hello World!" };
        var win = ss.Query.All<MyEntity>().Count(); //0
        ss.SaveChanges();
        var win1 = ss.Query.All<MyEntity>().Count(); //1
    }
    var win2 = session.Query.All<MyEntity>().Count(); //1
    session.CancelChanges();
}

using (var session = domain.OpenSession(scfg))
{
    var fail = session.Query.All<MyEntity>().Count(); //1
}
(Mar 16 '11 at 11:15) xumix xumix's gravatar image

Session.SaveChanges opens a db transaction, persists all changes and commits the transaction.

Session.CancelChanges forgets all registered changes made to entities starting from the last Session.SaveChanges call. So in your sample, Session.CancelChanges does nothing, all changes are already persisted 2 lines earlier and nothing has been modified yet.

(Mar 16 '11 at 11:20) Dmitri Maximov Dmitri%20Maximov's gravatar image

Yes, that exactly what I dont want. I want nested-transaction-like behavior, and I cant achieve it with ClientProfile. This is the main purpose of this topic.

(Mar 16 '11 at 11:24) xumix xumix's gravatar image

Thanks for your patience, it seems that finally I've caught the idea. You want to use Session.SaveChanges inside transaction scopes and thus, control what and when is being persisted to a storage.

Not so good news: due to the current architecture, for now such a behavior could be provided by ServerProfile only and not by ClientProfile.

(Mar 16 '11 at 11:36) Dmitri Maximov Dmitri%20Maximov's gravatar image

I see, thank for explaining. Any ETA for implementation? Or some workarounds? Add to feature requests maybe?

(Mar 16 '11 at 11:43) xumix xumix's gravatar image

Let us take an investigation on the subject. After that we'll publish updated info here. Is this acceptable?

(Mar 16 '11 at 11:45) Dmitri Maximov Dmitri%20Maximov's gravatar image

Yes, definetely, tnanks!

(Mar 16 '11 at 11:47) xumix xumix's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA