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

Entities from GetAll<T> not returned until AFTER SaveChanges() is called

2 Answers 28 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.
Mark
Top achievements
Rank 1
Mark asked on 03 Jul 2015, 03:05 PM

I am trying to incorporate Telerik Data Access (using SQLite) into some new development.

One of the requirements is to try to insert data into a table, but only if it does not already exist (using a Unique "Code" value to check the existence, rather than the PK id).

The plan was to use the DataContext as a transaction, so that multiple records can be committed at once, and easily roll backed if an error occurs.

For this to work, the entities to be inserted need to be queried along with the entities already in the database.

 

I was under the assumption that this is a standard feature of an ORM, and was expecting this to work straight out of the box. Am I missing a setting or something?

 

Here's some code that may help explain what I'm talking about:

[TestMethod]
public void when_a_record_is_inserted_it_should_be_retrievable_BEFORE_save_changes_is_called()
{
    var testTable = new TestTable()
    {
        Id = 1,
        UniqueValue = "Test",
        OtherValue = "Testing 123"
    };
 
    using (var dataContext = new TestFluentModel.TestFluentModel())
    {
        dataContext.Add(testTable);
 
        var toBeInserted = dataContext.GetChanges().GetInserts<TestTable>().SingleOrDefault(x => x.UniqueValue == "Test");
        Assert.IsNotNull(toBeInserted); //THIS WORKS, BUT WOULD MEAN ALL MY "GETS" WOULD NEED TO SEARCH THIS AS WELL AS GETALL
 
        var contextOnlyRecord = dataContext.GetAll<TestTable>().SingleOrDefault(x => x.UniqueValue == "Test");
        Assert.IsNotNull(contextOnlyRecord); //THIS FAILS
 
        dataContext.SaveChanges();
 
        var dbRecord = dataContext.GetAll<TestTable>().SingleOrDefault(x => x.UniqueValue == "Test");
        Assert.IsNotNull(dbRecord); //THIS WOULD WORK, BUT ONLY BECAUSE THE RECORD IS NOW IN THE DB
    }
}

 

 

2 Answers, 1 is accepted

Sort by
0
Mark
Top achievements
Rank 1
answered on 03 Jul 2015, 03:41 PM

After a lot of searching in your forum, I think I may have just solved this.

From this post back in 2011

http://www.telerik.com/forums/transaction-handling

 

The suggesting is to user

dataContext.FlushChanges();

After dataContext.Add(T) is called.

 

This has solved my problem, but I'd still like some confirmation that this is the correct solution? 

Is there not a setting to force a Flush after exery Add/Update/Delete?

 

 

0
Simeon Simeonov
Telerik team
answered on 08 Jul 2015, 02:11 PM

Hi Mark,

Thank you for contacting us.

The first thing you need to know is that the Add() method does not open a transaction to the database. If you want to send the pending data to the database you need to execute FlushChanges() or SaveChanges().

For your particular case if you want to use FlushChanges() you will need to:
1/ Set the context IsolationLevel to IsolationLevel.ReadUncommitted in order for the GetAll() method to get also the newly added records (instead of only those that are in the database). For more details you can read this article.
2/ Call FlushChanges() after every Add() call.

This approach is not ideal for the performance of your application.

Your initial approach of checking not only with GetAll(), but also checking the pending inserts (with .GetChanges().GetInserts()) is preferable. It is better to check the pending inserts after each Add() then calling FlushChanges() after each Add(). For this reason I would recommend that you use this approach.

I would also recommend that you add a database unique constraint for the "UniqueValue" column. This will add validation on the database level that you don't create records with the same value in this column. For more details you can see this article and more specifically the use of the IsUnique().

I hope you find this information helpful.

Regards,

Simeon Simeonov
Telerik
 
Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
Tags
Development (API, general questions)
Asked by
Mark
Top achievements
Rank 1
Answers by
Mark
Top achievements
Rank 1
Simeon Simeonov
Telerik team
Share this question
or