How to execute a custom sql statement in LLBLGen 3.1 (self servicing)? - llblgenpro

Using LLBLGen 3.1 (Self Servicing) on SQL Server, how would one execute custom SQL, such as:
delete from UserPreference
select * from UserPreference (into a datatable, for example)

Just noticed this question hadn't been answered. With Self Servicing, you'll probably use the TypedListDAO class.
See: Generated code - Fetching DataReaders and projections, SelfServicing
The TypedListDAO class has what you need to do SQL against your database, and it can automatically do projections onto custom classes for you if you need that (see the article).
But basically, (from memory, so might need some slight adjustments), here's what your code might look like:
// inside the DaoClasses namespace of your generated project
TypedListDAO dao = new TypedListDAO();
// do it yourself, and use your project's connection string
string connectionString = CommonDaoBase.ActualConnectionString;
using (var conn = new SqlConnection(connectionString)) { }
// use a DbConnection directly
DbConnection connection = dao.CreateConnection();
// or
connection = dao.DetermineConnectionToUse(null);
DbCommand cmd = connection.CreateCommand();
cmd.CommandText = "SELECT * FROM UserPreferences";
cmd.CommandType = CommandType.Text;
var reader = cmd.ExecuteReader(CommandBehavior.Default);
while (reader.Read()){}
reader.Close();
// use a datareader
IRetrievalQuery query = new RetrievalQuery(
new SqlCommand("SELECT * FROM UserPreferences"));
// or new RetrievalQuery(cmd);
// where you create the cmd using the dao connection
IDataReader reader = dao.GetAsDataReader(null, query,
CommandBehavior.CloseConnection);
while (reader.Read()){}
reader.Close();
// use a datatable - try something like this
// (BUT honestly, you might want to look at the custom projection
// into custom classes capability, or the data reader, instead of this)
DataTable dt = new DataTable();
dao.GetMultiAsDataTable(new EntityFields(0) /* can't be null, i don't think */,
dt, query, null);
// other methods
dao.ExecuteScalarQuery(query, null);
ActionQuery actionQuery = new ActionQuery(new SqlCommand("INSERT ..."));
dao.ExecuteActionQuery(actionQuery, null);
OR, use a micro-orm to do your sql, and just use the connection from the TypedListDAO class above
Some Light-weight micro-orms, like: Dapper (1 cs file), PetaPoco, Massive, etc...

While it is true that you can access the low level data readers, etc.. I think it kind of defeats the purpose of using the ORM. If you just want to fill a datatable from a collection (with or without filtering), you can use the static method GetMultiAsDataTable (which you can pass a predicate expression to if you want to do filtering). If you want to replace more complex SQL (very useful for reporting), check out the dynamic lists capabilities:
http://www.llblgen.com/documentation/4.0/LLBLGen%20Pro%20RTF/hh_start.htm
The QuerySpec is an even nicer way to specify a dynamic query and project it:
http://www.llblgen.com/documentation/4.0/LLBLGen%20Pro%20RTF/hh_start.htm

Related

How to remove table names in JDBC response in SOAPUI

In SOAPUI tool, in response for any DB step, response contains with tableName.column.
please refer the below image.
How can remove the tableName attribute from the response.
I mean to ask, is there any setting in SOAPUI or is there any properties file I need to update...
This doesn't depends on settings from SOAPUI, it's depends on DB drivers.
I follow the SOAPUI code from github, and I finally found that internally JDBCTestSteps constructs the XML node names from response based on the follow code fragment:
...
public static Document addResultSetXmlPart(Element resultsElement, ResultSet rs, Document xmlDocumentResult)
throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
...
...
String columnName = "";
if (!StringUtils.isNullOrEmpty(rsmd.getTableName(ii))) {
columnName += (rsmd.getTableName(ii)).toUpperCase() + ".";
}
columnName += (rsmd.getColumnName(ii)).toUpperCase();
String value = rs.getString(ii);
Element node = xmlDocumentResult.createElement(StringUtils.createXmlName(columnName));
...
(You can see the whole method addResultSetXmlPart method form XMLUtils class here)
So as you can see the node name on the XML depends on ResultSetMetaData getTableName and getColumnName methods. This class is an interface and the implementation of these methods depends on specific DB driver version.
So to have the same behavior as your client, simply check that both have the same DB drivers in SOAPUI_HOME\bin\ext.
REMARK: Once you or your client change the .jar in SOAPUI_HOME\bin\ext restart SOAPUI in order to load the new ones.
Hope this helps,
"postgresql-9.1-903.jdbc4" should return the resultset without the table names. I got it working without placing the db driver to the SOAPUI_HOME\bin\ext.

How to read columns of SQL Server tables in Visual Studio?

In Microsoft Access functions like DLookup - DMax or Dcount help the programmer to read a column from a table of a SQL Server database.
How do you do the same task in Visual Studio?
For example how can I find the ID of a user (John) in tblUsers table.
tblUsers columns: ID, Username, Password, .....
I've already added the SQL Server database to the Data Source.
Any kind of advice is much appreciated.
ow. Even in Access, that isn't proper.
Go read up on DAO, ADO, and, if you're using Visual Studio to write .Net applications, the system.data namespace.
in general, when accessing relational data via non-database program code, including the vba you're using in Access, you'd retrieve a reference to a Recordset object and query each record's fields as object properties.
If you want to visualize all of the data, click Database Explorer (see the tab at the bottom of the solution explorer), then expand your data connections and right click the name of the table, then click 'show table data'. If you want only the id's or names etc, I usually just create an SQL script to run, and run it when I want to browse certain data.
To simply create a script, while you're viewing all the data, click the script button above the table your viewing. Then you can execute your script
SELECT * FROM tblUsers WHERE User = 'John';
I hope I've understood your questions correctly.
I followed DougM and ended up with the following code. I will add it here just in case somebody else has the same question:
using System.Data.SqlClient; should be added to the reference section
private void button1_Click(object sender, EventArgs e)
{
string fltr = "UserName='Ando'";
MessageBox.Show(ReadOrderData(fltr));
}
public string ReadOrderData(string filter)
{
string connectionString = "Data Source=sqlServer-servername;Initial Catalog=database name;Integrated Security=True";
string queryString = "SELECT User_ID, UserName FROM tblUsers WHERE " + filter + ";";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
return reader[0].ToString();
//Console.WriteLine(String.Format("{0, {1",
// reader[0], reader[1]));
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
return "Null";

Issue Retrieving a Screenshot from a database

I've got a bunch of screenshots and some screenshot meta data I'm trying to display in an ASP.NET MVC 3 web application, I'm trying to retrieve the data from my databse but I get this error:
LINQ to Entities does not recognize the method 'System.Drawing.Image
ByteArrayToImage(Byte[])' method, and this method cannot be translated
into a store expression.
Here's my code:
var screenshotData = (from screenshots in db.screenshots
where screenshots.projects_ID == projectID
select new ImageInformation
{
ID = screenshots.id,
Language = screenshots.language,
Screenshot = Utility.ByteArrayToImage(screenshots.screen_shot),
ProjectID = screenshots.projects_ID
});
foreach (ImageInformation info in screenshotData)
{
this.Add(info);
}
ImageInformation is just a simple class that contains the defintion the information stored (ID, Language, Screenshot, ProjectID).
Here's my ByteArrayToImage function:
public static Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
Can anybody tell me why I receive this error when this code runs?
Thanks.
I think it's because, with LINQ-to-Entities, the code is turned into server-side query and it can't do that in this case. I don't think you can mix client-side code like this directly with L2E.
I would suspect you will have to do the conversion from byte->image after you've retrieved the data from the database as a distinct step.
You can't do the function in a LINQ to Entities query... one option:
1) have a byte[] property on the object you are instantiating (ImageInformation) and copy the data in there along with another propery to read the image from this ImageInformation object.

Dapper with MVCMiniProfiler

I am wanting to use the MVCMiniProfiler with Dapper. Is this possible beyond wrapping the "Query" call from dapper in "Using Profiler.Step" block?
I have this basic Dapper call:
Dim comments As List(Of Comment)
Using conn = New SqlConnection(ConnectionString)
conn.Open()
comments = conn.Query(Of Comment)("SELECT * from comments where userid = #userid", New With {.userid= 1})
End Using
The MiniProfiler examples show this
Private Shared _sqlConnection As SqlConnection
Public Shared Function GetOpenConnection() As DbConnection
If _sqlConnection Is Nothing Then
_sqlConnection = New SqlConnection("connection string")
End If
' wrap the connection with a profiling connection that tracks timings
Return MvcMiniProfiler.Data.ProfiledDbConnection.[Get](_sqlConnection, MiniProfiler.Current)
End Function
Where I am stuck is in the implementation of the "Get" on the ProfiledDbConnection. Is it possible to use ProfiledDbConnection while using Dapper?
Good catch, the documentation is out of date, just updated it:
Use something like:
return MiniProfiler.Current != null ?
new MvcMiniProfiler.Data.ProfiledDbConnection(cnn, MiniProfiler.Current) :
cnn;
I killed the factory cause I wanted people to be able to inherit off ProfiledDbConnection and statics can not be virtualized.

LINQ CRM 2011 Update - Create

I notice the the CRM moderator David Jennaway on the technet forum states that you can't use LINQ to update/Create records in CRM 2011 see here http://social.microsoft.com/Forums/en-IE/crmdevelopment/thread/682a7be2-1c07-497e-8f58-cea55c298062
But I have seen a few threads that make it seem as if it should work. Here is my attempt which doesn't work. Any ideas why not?
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
OrganizationServiceContext orgContext = new OrganizationServiceContext(service);
EntityState state = new EntityState();
state = EntityState.Changed;
var counter = from c in orgContext.CreateQuery<pcx_entitycounter>()
where c.pcx_name.Contains("pcx_candidate")
select new pcx_entitycounter
{Id = c.Id,
pcx_name = c.pcx_name, pcx_Sequence = c.pcx_Sequence, pcx_Prefix = c.pcx_Prefix
};
foreach (var c in counter)
{
string prefix = c.pcx_Prefix.ToString(); ;
string sequence = c.pcx_Sequence.ToString();
c.pcx_Sequence = c.pcx_Sequence + 1;
c.EntityState = state;
**service.Update(c);** //FAILS HERE
}
In my experience, it's been difficult-to-impossible to retrieve an entity from the Context, update it, then use the Service to save the changes. It has caused me headaches figuring it out!
Since your retrieval code uses a query from the Context, all of those entities should be attached to the Context and their states are being tracked. Thus you need to use the Context's method for updating:
foreach (var c in counter) {
string prefix = c.pcx_Prefix.ToString(); ;
string sequence = c.pcx_Sequence.ToString();
c.pcx_Sequence = c.pcx_Sequence + 1;
// Use the Context to save changes
orgContext.UpdateObject(c);
orgContext.SaveChanges();
}
Since a lot of my code will retrieve entities in different ways (i.e. Service or Context) depending on the situation, I have developed a simple method that knows how to update the entity correctly. To expand on your example, you might have an update method that looks like:
public void UpdatePcxEntityCounter(pcx_entitycounter c) {
if (!orgContext.IsAttached(c)) {
service.Update(c);
}
else {
orgContext.UpdateObject(c);
orgContext.SaveChanges();
}
}
This assumes both orgContext and service are available at a scope above that of the method. Otherwise, they'd have to be passed as additional parameters.
Without seeing the difficult its difficult to discern what the issue is but have you tried using orgContext.UpdateObject(c); before doing the update step? Also, not sure why you are assigning the prefix and sequence to local variables within your loop since they don't appear to be being used. Its possible that you are getting a SOAP Exception or something for assigning values that don't work. Do you have any plugins registered on the entity?
See the following links for possible resolutions -
How to update a CRM 2011 Entity using LINQ in a Plugin?
http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/7ae89b3b-6eca-4876-9513-042739fa432a

Resources