Does ria services have something like sqlclient SqlCommand for executing T-SQL? - wcf-ria-services

How would ria services do this kind of thing?
using (SqlConnection connection = new SqlConnection(connectionString))
{
string TSQL="update products set price=price*1.03 where category='computer books'";
SqlCommand command = new SqlCommand(TSQL, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
Thanks, Mark

You need get all entites of Product with category computer books and then update price for them and save changes to DB.

Related

.NET: NpgsqlCommand to IQueryable

Is there a way to create an IQueryable from an NpgsqlCommand?
Something like this:
using (var connection = new NpgsqlConnection(_connectionString))
{
connection.Open();
using (var cmd = new NpgsqlCommand("SELECT o.Id, o.Name FROM schema.blogs", connection))
var blogsQueryable = cmd.Execute<IQueryable<BlogViewModel>>;
}
Npgsql on its own is just an ADO.NET provider, and as such does not map rows to your own objects.
You should take a look at Entity Framework Core for a full O/RM, or at Dapper for a lighter solution.

Multiple connections in one transaction, on Azure

We are building an application, that is using a legacy framework utilising ADO.NET. This framework manages its own connection to the DB for calls to its code API.
For any customisations and custom tables we are using Entity Framework and hence a separate connection to the DB is made.
The application and DB is to be hosted on Azure.
What we would like to do is wrap both calls to the legacy framework and to Entity Framework into the same transaction.
Our understanding is that this is a distributed transaction, but this feature is not available in Azure.
Is there a way to make this to work in the Azure environment?
e.g.
using (var transaction = new TransactionScope())
{
using (var db = new EntityFrameworkDBEntities())
{
Order order = db.Orders.FirstOrDefault();
order.Name = "1";
db.SaveChanges();
}
using (var legacyAPI = new LegacyAPI())
{
Customer customer = legacyAPI.GetCustomers.FirstOrDefault();
customer.Name = "Charles";
legacyAPI.SaveCustomer(customer);
}
transaction.Complete();
}
AFAIK you need to use the same connection for your transaction since SQL Azure doesn't support distributed transaction. ADO.NET will upgrade to distributed transaction if you utilizes multiple connections in the same transaction even though all of them are connected to the same database.
As Shaun Xu says, you need to use just one connection. If you are able to change your LegacyAPI to take an open connection and a transaction as input, here is how, using EF6 and edmx:
var workspace = new MetadataWorkspace(new[] { "res://*/" }, new[] { Assembly.GetExecutingAssembly() });
using (var connection = new SqlConnection("Normal ADO connection string with MultipleActiveResultSets=True"))
{
using (var entityConnection = new EntityConnection(workspace, connection, false))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
using (var db = new EntityFrameworkDBEntities(entityConnection))
{
db.Database.UseTransaction(transaction);
// Do stuff with db
db.SaveChanges();
}
// Do ADO stuff on LegacyAPI using the connection and transaction objects
transaction.Commit();
}
}
}
To obtain the extra constructor on your dbcontext, you make this partial class, where false indicates that you open and close the connection manually.
partial class EntityFrameworkDBEntities
{
public EntityFrameworkDBEntities(DbConnection connection) : base(connection, false) { }
}
As a bonus you now only need one connection string in your config and it doesn't include all the useless EF junk that normally comes with it (metadata=res://*/blabla).
This also works if, say, you have a database with multiple schemas and an edmx for each. Note that although the EntityConnections are identical, you need one for each dbcontext.

How to set UserID and Password in EnterpriseLibrary 6.0

I have coded like the below:
#Code
DatabaseProviderFactory factory = new DatabaseProviderFactory();
database = factory.Create("DBinstanceName");
ConfigFile Entries
<oracleConnectionSettings>
<add name="CNQ" />
</oracleConnectionSettings>
<connectionStrings>
<add name="CNQ" connectionString=" Min Pool Size=0;Connection Lifetime=120;Max Pool Size=50; Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST= XXXX.com)(PORT=1521))) (CONNECT_DATA = (SID = cnq) (SERVER = DEDICATED) ) );"
providerName="Oracle.DataAccess.Client" />
</connectionStrings>
With the above code and config settings, the DatabaseObject is created perfectly. When I verify the connectionstring it has the values what I had mentioned in the connnection string. So far good.
Now, I have to add the UserId & Password to the connection string at the runtime. There is no methods I could find to add the user credentials to the existing connection string. Becuase, in the Database object the connection string is READ ONLY.
The only way I find is to set in the configuration file[App.config], which is not the way we want, because for every user, we have a separate userid and password in the Oracle database.
In fact, I had tried by settings the connections at the command object, and passed the command object to the execute reader, even then also the enterprise library 6.0, not taking the connection we set in the command object.
Please help us how to set the userid and password in the runtime.
Thanks in advance
In order to set connection string values at runtime you will have to programmatically create your database objects. For example:
Database database = new GenericDatabase(GetConnectionString(),
DbProviderFactories.GetFactory("Oracle.DataAccess.Client"));
Or if you are using OracleDatabase something like:
OracleDatabase database = new OracleDatabase(GetConnectionString());
You could use extension methods to hide a bit of the ugliness:
DatabaseProviderFactory factory = new DatabaseProviderFactory();
Database db = factory.CreateWithConnectionString(GetConnectionString(),
DbProviderFactories.GetFactory("Oracle.DataAccess.Client"));
db = factory.CreateOracleDatabase(GetConnectionString());
public static class DatabaseProviderFactoryExtensions
{
public static Database CreateWithConnectionString(this DatabaseProviderFactory factory,
string connectionString,
DbProviderFactory dbProviderFactory)
{
return new GenericDatabase(connectionString, dbProviderFactory);
}
public static Database CreateOracleDatabase(this DatabaseProviderFactory factory,
string connectionString)
{
return new OracleDatabase(connectionString);
}
}
Another way to approach the issue if you know what connections you will have in advance (still at runtime but perhaps at application startup) is to use the DatabaseFactory.SetDatabases method to return the correct database based on a key. Unfortunately, the method only takes a single string so you can't specify nicely the username and password but you might be able to do something like this:
DatabaseFactory.SetDatabases(() => GetDatabase("Default"),
(dbName) => GetDatabase(dbName));
Database db = DatabaseFactory.CreateDatabase();
public Database GetDatabase(string dbName)
{
string connectionString = GetConnectionString(dbName);
return new OracleDatabase(connectionString);
}
Where the GetConnectionString method can create the proper connection string based on a name. However, I'm guessing this last way might not be the best given your description.
Thanks for your response.
Because I am using the Enterprise Library 6.0, only the First answer only works.
Database database = new GenericDatabase(GetConnectionString(),
DbProviderFactories.GetFactory("Oracle.DataAccess.Client"));
[or]
Oralce.DataAccess.Client.OralceClientFactory ocf = new Oracle.DataAccess.Client.OracleClientFactory();
Database database = new GenericDatabase(GetConnectionString(), ocf);
Thanks

Unable to persist Entities to SQL CE using entity framework

I am stating out with entity framework. I have created my ADO.NET Entity Model and mapped the entities to a local SQL CE database file (all done via the wizards). I have created a unit test to test the data access and see how things work. The test executes fine and without any exceptions. However, no new row is generated in the database. Please Help!!!
public void TestCreateRelationshipType()
{
using (var c = new TenderModelEntities())
{
IList<RelationshipType> types = c.RelationshipTypes.ToList<RelationshipType>();
int num1 = types.Count();
RelationshipType type = new RelationshipType();
type.Description = "New Client";
c.AddToRelationshipTypes(type);
c.SaveChanges();
IList<RelationshipType> types2 = c.RelationshipTypes.ToList<RelationshipType>();
int num2 = types2.Count();
Assert.AreEqual(num1 + 1, num2);
}
}
New row is added to the database because you call the SaveChanges() function. When you call this on your datacontext, the changes are passed on to the database.
If you don't want to make any changes to the database, just comment out this section like below
// c.SaveChanges();

Running sql in entity framework?

Is there any way to run a sql statement straight from the entity framework generated calls? Or will I have to create a procedure then call that via the entity framework?
Was Googling around for this myself the other day, this is the example I found hope it helps
static void ExecuteSql(ObjectContext c, string sql)
{
var entityConnection = (System.Data.EntityClient.EntityConnection)c.Connection;
DbConnection conn = entityConnection.StoreConnection;
ConnectionState initialState = conn.State;
try
{
if (initialState != ConnectionState.Open)
conn.Open();
using (DbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
}
}
finally
{
if (initialState != ConnectionState.Open)
conn.Close();
}
}
In EF 4.0 this is pretty easy because there are new methods on the ObjectContext that allow you to execute store commands (i.e. SQL) directly:
See this: ExecuteStoreCommand
If you are still using EF 3.5 SP1 you can still execute a query directly against the database if you really want to like this:
var econn = ctx.Connection as EntityConnection;
var dbconn = econn.StoreConnection;
at this point you have access to a connection (dbconn) to the underlying database, so you can use normal ADO.NET code to execute queries etc.
Hope this helps
Alex
ExecuteStoreQuery<> and ExecuteStoreCommand is what you want:
using (NorthWindEntities ctx = new NorthWindEntities())
{
ctx.ExecuteStoreQuery<>()
ctx.ExecuteStoreCommand();
}
#Alex James, out of curiosity, would this be efficient to run a full text sql bit of code, as in there should be no performance overhead right? To say, running the same full text sql code straight as a query in sql management studio.