Enterprise Library question - enterprise-library

what is the difference between the below two statements? which one is more efficient?
Database db = EnterpriseLibraryContainer.Current.GetInstance("QuickStarts Instance");
Database db = DatabaseFactory.CreateDatabase();

They are functionally identical. DatabaseFactory just turns around and calls the first line.
The DatabaseFactory is part of the older API based around static facades that Entlib is moving away from. The call to EnterpriseLibraryContainer is more future proof, and it has the advantage of being a single entry point that works regardless of which block you're using.

Related

ADO.NET Best Practices for Connection and DataAdaptor Object Scope - follow-up

I had the exact same question that was asked by Mark Lansdown some time ago. Mark's question
The answers in that thread were somewhat helpful but left me still extremely puzzled; particularly as it relates to the recommended practice of employing "using" blocks.
The first answer seemed to indicate that the Connection object and the DataAdapter object should be created within using blocks...
DataTable dt = new DataTable();
using (OleDbConnection conn = new OleDbConnection("my_connection_string"))
using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Employees", conn))
{
adapter.Fill(dt);
}
Thus, the DataTable object is retained but both the DataAdapter and Connection object go out of scope the instant the table is filled.
Yet a follow-on answer indicated that the DataAdapter Object should be retained. That makes perfect sense to me as it does appear to me that the DataAdapter was designed with handling multiple commands in mind.
So this leaves me with multiple questions:
BTW, I am using vb.net with SQL Server
Question 1) In order to retain the DataAdapter object doesn't that mean I cannot create it with a using block?
Question 2) In order to create an instance of a DataAdapter don't I need an instance of a Connection object which would make it impractical to create the Connection object with a using block?
How would I implement the using blocks in code like this?
Private Class frmMain
Dim adapter as SqlDataAdapter
Dim conn as SqlConnection
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
conn = new SqlConnection("My_Connection_String")
adapter = new SqlDataAdapter("Select * from Employees", conn)
adapter.fill(MyDataSet, MyTableName)
End Sub
Private Sub SaveButtton_Click(sender as Object, e As EventArgs) Handles SaveButton.Click
adapter.Update(MyTableName)
End Sub
End Class
I have seen a bunch of sample code for all this on msdn and every sample code I saw incorporated using blocks but always created a table via code and performed updates via code all inside the using blocks which seems to me like it could never work in the real world.
Thanks for any advice.
a follow-on answer indicated that the DataAdapter Object should be retained...
Question 1) In order to retain the DataAdapter object doesn't that mean I cannot create it with a using block?
No. The response is flawed. Remember, DataAdpater was in .Net 1.0. At this time there was no good way to dispose your objects, so you did the best you could. Using blocks and good IDisposable support were added for .Net 2.0, and this caused a change in direction for how things should be done. Yes, a DataAdapter can have different kinds of queries, and has the ability to support longer lifetimes if that's really want you want, but it's rarely a good choice anymore to use it that way.
If you really want, you can still create another DataAdapter later on if you need it for the different type of query, or you can use ExecuteNonQuery() for things like DELETE, INSERT, and UPDATE. But if you want the framework to do more of that kind of work for you, you should really go for a full ORM. If you want to write your own SELECT statements in code, you're usually better off also writing your own INSERT, UPDATE, and DELETE (etc) statements by hand, as well (and be sure to use parameterized queries!).
Question 2) In order to create an instance of a DataAdapter don't I need an instance of a Connection object which would make it impractical to create the Connection object with a using block?
How would I implement the using blocks in code like this?
Don't write code like that. Rather than repeat myself I'll link to a previous answer explaining why:
https://softwareengineering.stackexchange.com/questions/142065/creating-database-connections-do-it-once-or-for-each-query/398790#398790
But the short version is an ADO.Net connection object is a thin wrapper around much "heavier" and more expensive items in a connection pool. When you try to re-use a connection throughout a class or application, you gain efficiency in the relatively cheap wrapper at the expense of the much larger real underlying connections. You really are much better off creating a new connection each time. Only the connection string should be preserved for re-use.
every sample code I saw incorporated using blocks but always created a table via code and performed updates via code all inside the using blocks which seems to me like it could never work in the real world.
I assure you, it works very well. Again, if you don't like it, maybe you're looking for a full ORM like EntityFramework.

Why is the process of obtaining ObjectContext from dbContext so slow?

I use in my work Entity Framework Code first (6.2). One of the biggest problem with such approach is slow performance at first query. I use InteractiveViews nuget package to workaround this issue, but unfortunately, it doesn't give expected productivity growth.
When I was experimenting with source code, i noticed that
**( dbContext as IObjectContextAdapter).ObjectContext**
took i very long time ( 8 sec. in my case).
Q: What is the reason for the such big delay? Is it normal or it possible somehow to solve?
new DbContext
Creating a new context such as var ctx = new DbContext() doesn't make the model to be compiled or do any database verification with the Migration History table.
It could take 500ms because it JIT compiles some method within Entity Framework or another third library that you may call in your constructors.
It's hard to know why it takes 500ms because they might have several reasons.
(dbContext as IObjectContextAdapter).ObjectContext
Doing it mean the OnModelCreating method will be invoked, and the model will be compiled for the first time. Some query will be executed on the database as well.
The best way to find out is making a simple test, adding some break point, and enabling SQL Profiler to see it by yourself:
var ctx = new CurrentContext1();
var objectContext = (ctx as IObjectContextAdapter).ObjectContext;
You will suffer from the same performance problem as people usually report when they ask Why Entity Framework First Load is Slow

Correct way to persist and existing JPA entity in database

In one application I am working on, I found that the JPA objects that are modified are not previouly loaded, I mean;
Instead of doing like this:
getEntityManager().find(Enterprise.class, idEnterprise);
//Some modifying operations
They do like this(and works!):
Enterprise obj = new Enterprise (IdEnterprise);
//Some modifying operations
getEntityManager().persist(obj);
This last solution doesnt load from database the object and it modifies the object correctly.
How is this possible?
Is a good practice? At least you avoid the query that loads from database, right?
Thanks
It depends. If you are writing code from a controller class (or any application code) you shouldn't be worried about jpa stuff, so the second approach is bad and redundant.
If, instead, you are working in infrastructure code, maybe you can manually persist you entities to enable some performance optimization or simply because you want the data to persist even if the transaction fails.
I strongly suspect the second bit of code is someone creating an entity from scratch, but mixing application, domain and infrastructure code in the same method: an extremely evil practice. (Very evil, darth father evil, never do that)

EnterpriseLibrary, EF, and Transaction Scope: why am I seeing different behavior?

I have one app that uses EnterpriseLibrary and Unity, and uses TransactionScope in just one place. This works nicely, despite the fact that it runs against SQL Server 2005:
// Execute a stored proc using a DbDatabase object inserted by Unity
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
// Update something using the same DbDatabase object
// Run the stored proc above, again
// Assert that the results are different than from the previous call.
}
Yes, this deliberately ends without a scope.Complete(): the example is from a test.
I also have another application just beginning. It uses Entity Framework 4.1. It accesses the same database on the same server. I attempted to use TransactionScope, with the same "make change, verify change, roll back change" idea in mind.
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
using(ProjectEntities db = new ProjectEntities())
{
Assert.IsFalse(db.tblEntities.Any(e=>e.X == desired_value));
db.tblEntities.Add(new tblEntity() { X = desired_value });
db.SaveChanges();
Assert.IsTrue(db.tblEntities.Any(e=> e.X == desired_value));
}
}
This fails with the very familiar error about MSDTC not being enabled for network access.
Right now, this minute, the first test in the first project succeeds, the second test fails.
So I have two questions:
Is there a way to rejigger my second test that would keep the transaction from escalating to MSDTC?
Anybody know why I'm getting different results from the two frameworks? Does EntLib keep a single connection allocated and open during the whole time it's used? Does EF do the opposite?
I have made many test regarding EF, EntLib DAAB, and TransactionScope.
There are several points you must take into account.
SQL Server Version
Connection String
EF and EntLib version
I don't remember the other combinations, but with SQL Server 2008 or later, EF5, and Entlib 5, you can enroll several DbContexts and DAAB operations in the same TransactionScope without scalating to MSDTC. But there's a very tricky part:
the connection string must include: MultipleActiveResultSets=true;
the connection string must have the exact format used by EF
The second part is the most confusing: when you use a connection string to EF, it will chaneg its format, but EntLib uses it as is in the connection string of the config file. So, what you have to do is debug the code, and note down the modified version of the connection string used by EF. You can find it in ctx.Database.Connection.ConnectionString, where ctx is the DbContext you're using. Once you've done so, just copy and paste the modified version of your connection string to your config file, and both EF and EntLib will use the same connection string, thus not escalating to MSDTC.
For previous versions of SQL Server (and sometimes depending on EF version) you can find different problems, but this guidelines can help you test your exact setup.
I don't know about the EnterpriseLibrary but EF does create and open new connection for every query and I think this is why you see those different results.
You can verify this by opening two DbConnections by hand.

How to run two Entity Framework Contexts inside TransactionScope without MSDTC?

This problem is not readily reproducible in a simple example here but was wondering if anyone has any experience and tips, here is the issue:
using Entity Framework
have many points in application where (1) data is written to some entity table e.g. Customer, (2) data is written to history table
both of these actions use Entity Framework, HOWEVER, they use different contexts
these actions need to be both in one transaction: i.e. if one fails to write, the other should not write, etc.
I can wrap them with a TransactionScope,
like this:
using (TransactionScope txScope = new TransactionScope()) {
...
}
but this gives me:
Microsoft Distributed Transaction Coordinator (MSDTC) is disabled for
network transactions.
Our database admin has told me that MSDTC is disabled by choice and can not be installed.
Hence I am making changes trying to create my own EntityConnection with a MetadataWorkspace with the idea that each context will use the same EntityConnection. However, this is proving near impossible trying to get it to work, e.g. currently I continue to get the above error even though theoretically both contexts are using EntityConnection. It's difficult to understand where/why Entity Framework is requiring the MSDTC for example.
Has anyone gone down this road before, have experience or code examples to share?
Well, the problem is quite easy.
If you are using sql server 2008 you should not have that problem because you have promotable transaction, and as .NET knows that you are using the same persistence store (the database) it wont promote it to DTC and commit it as local. look into promotable transaction with sql server 2008.
As far as I know Oracle is working in its driver to support promotable transactions, but I do not know the state, MS oracle driver does not support it.
http://www.oracle.com/technology/tech/windows/odpnet/col/odp.net_11.1.0.7.20_twp.pdf
If you are using a driver that do not support promotable transactions it is impossible for .NET to use local transaction doing two connections. You should change your architecture or convince the database admin for installing MSDTC.
I had a similar problem with SQL 2008, Entity Framework.
I had two frameworks defined (EF1, and EF2) but using identical connection strings to a sql 2008 database.
I got the MSDTC error above, when using nested "usings" across both.
eg the code was like this:
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
}
dbContext.Complete();
}
It wasnt as simple as this, because it was split across several methods, but this was the basic structure of "usings".
The fix was to only open one using at a time. No MTDSC error, No need to open distributed transactions on db.
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
}
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
dbContext.Complete();
}
I think that what you need to do is to force your contexts to share single database connection. You will be able then to perform these two operations against two different contexts in single transaction. You can achieve this by passing one EntityConnection object to both of your context's constructors. Of course this approach will require you to pass this object to methods which update DB.
I have recently blogged about creating database context scope which will make using multiple EF contexts and transactions easier.