var retval = db.TestTable.SqlQuery("SELECT * FROM dbo.TestTable WHERE " + aColumn + " = '" + passedInValue + "'");
// normally when using parameters I would do something like this:
var valueParam = SqlParameter("aValue", passedInValues);
var retval = db.TestTable.SqlQuery("SELECT * FROM dbo.TestTable WHERE Column1 = #aValue", valueParam);
// NOTE: I would not do this at all. I know to use LINQ. But for this question, I'm concentrating on the issue of passing variables to a raw sql string.
But since both the column and value are "parameters" in:
var retval = db.TestTable.SqlQuery("SELECT * FROM dbo.TestTable WHERE " + aColumn + " = '" + passedInValue + "'");
, is there to prevent sql injection for both?
First: whilelist aColumn: this has to be added via string concatenation but you know what columns are in your database (or you can check using schema views).
Second: In entity framework – as you show – you can use parameters for values in the query. However, rather than creating SqlParameter instances you can pass the values and use #p0, #p1, ….
Right way to prevent SQL injection is to use SqlParameter and SqlQuery<T>:
var parameter = new SqlParameter("#title", value);
var result = context.Database.SqlQuery<Book>("SELECT * FROM Books WHERE Title LIKE #title", parameter);
http://ignoringthevoices.blogspot.ru/2013/07/sql-injection-with-entity-framework-5.html
Related
#Karney. this is my code
var customerMachineId = wcDataContext.Customers.Where(x =>
x.UserId.Equals(currentUser.Result.Id)).Select(x =>
x.MachineId).ToList();
var customers1 = (from customer in wcDataContext.Customers
join machine in wcDataContext.Machineinfo
on customer.MachineId equals machine.MachineId
where customerMachineId.Contains(customer.MachineId)
select new UserMachineInfo
{
Mac1 = machine.Mac1,
Mac2 = machine.Mac2,
MachineId = machine.MachineId,
MachineName = machine.MachineName,
UserId = customer.UserId,
UserName = customer.User.FirstName.ToString() + " " + customer.User.LastName.ToString()
//UserName = (customer.User.FirstName + " " + customer.User.LastName).ToString()}
.OrderBy(ti => ti.Inner.FirstName.ToString() + " " + ti.Inner.LastName.ToString())' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToList.
The error is given while querying data in jQuery datatables. I was trying to search data in a jQuery datatable. How can I rewrite this query to resolve error?
I need to know the correct way to handle SQL Injection when using the FromSQL command.
At runtime, I need to dynamically create a where statement. So I am using FromSql to create the SQL command. Now I know that using use string interpolation is the way to go. However, I need to step through a list of "Where Parameters" to generate the command. Simple enough to do;
foreach (var x in wp)
{
if (!string.IsNullOrEmpty(results))
results = $"{results} and {x.Field} = {x.Value}";
if (string.IsNullOrEmpty(results))
results = $"where {x.Field} = {x.Value}";
}
Problem is that this return a simple string and would not be string interpolation. How can I do this correctly?
Entityframework will parameterize your queries if you put it in the following format:
db.something.FromSql("SELECT * FROM yourTable WHERE AuthorId = {0}", id)
Is x.Field a form field that has a fixed number of possibilities? i.e. title, firstname etc. If so then something like the following:
var sqlstring = new StringBuilder();
var sqlp = new List<SqlParameter>();
var i = 0;
foreach (var x in wp)
{
var param = "#param" + i.ToString();
if (i!=0)
{
sqlstring.Append($" AND {x.Field} = " + param);
sqlp.Add(new SqlParameter(param, x.Value));
}
if (i==0)
{
sqlstring.Append($"WHERE {x.Field} = " + " #param" + i.ToString());
sqlp.Add(new SqlParameter(param, x.Value));
}
i++;
}
You'd then need to do something like this:
db.something.FromSql(sqlstring.ToString(), sqlp.ToArray())
Might be a better/cleaner way but that should work.
My solution to this problem is a VS extension, QueryFirst. QueryFirst generates a C# wrapper for sql that lives in a .sql file. As such, parameters are the only way to get data into your query and SQL injection is near impossible. There are numerous other advantages: you edit your sql in a real environment, it's constantly validated against your db, and using your query in your code is very simple.
I am building a BIRT report based on a dynamic table. I have a function that needs to return a table with variable number of columns of different types, so we have decided that this function will create a temporary table and just return its name.
So in the BIRT beforeFactory I am running the query that calls this function and then I am trying to read from the table of returned name and create a report table dynamically based on the number of columns and types. Two questions:
1. Is there a better way to return a table with variable number of columns? (this cannot be all the possible columns that I later filter as that would exceed maximum number of allowed columns)?
2. How to make Birt to see my temporary table? Here is the code, that I run in beforeFactory. Apparenty the table does not exists when calling second query.
importPackage(Packages.java.lang);
importPackage(Packages.org.eclipse.birt.report.data.adapter);
importPackage(Packages.org.eclipse.birt.report.data.adapter.api);
importPackage(Packages.org.eclipse.birt.report.data.adapter.impl);
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.data.engine.api.querydefn);
//Get Data Source
var dataSource =
reportContext.getDesignHandle().getDesign().findDataSource("mydb");
//Create Data Set for data table name
var elementFactory =
reportContext.getReportRunnable().designHandle.getElementFactory();
var dataSet = elementFactory.newOdaDataSet("tableName",
"org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet");
dataSet.setDataSource(dataSource.getName());
dataSet.setQueryText("select table_name from my_export_function('str1',
'str2');");
reportContext.getDesignHandle().getDataSets( ).add(dataSet);
//Create Data Session
var myconfig =
reportContext.getReportRunnable().getReportEngine().getConfig();
var des = DataRequestSession.newSession(myconfig, new DataSessionContext(3));
var dset = reportContext.getDesignHandle().findDataSet("tableName");
des.defineDataSource(des.getModelAdaptor()
.adaptDataSource(reportContext.getDesig nHandle()
.findDataSource("mydb")));
des.defineDataSet(des.getModelAdaptor()
.adaptDataSet(reportContext.getDesignHandle()
.findDataSet("tableName")));
//Query Definition
queryDefinition = new QueryDefinition();
queryDefinition.setDataSetName(dataSet.getName());
queryDefinition.setAutoBinding(true);
var pq = des.prepare(queryDefinition);
var qr = pq.execute(null);
var ri = qr.getResultIterator();
var tableName = "";
while (ri.next()) {
tableName = ri.getString("table_name");
}
var dataSet2 = elementFactory.newOdaDataSet("reportData",
"org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet");
dataSet2.setDataSource(dataSource.getName());
dataSet2.setQueryText("select * from " + tableName + ";");
System.out.println("TTTT: " + dataSet2.getQueryText());
reportContext.getDesignHandle().getDataSets( ).add(dataSet2);
//Query Definition
queryDefinition2 = new QueryDefinition();
queryDefinition2.setDataSetName(dataSet2.getName());
queryDefinition2.setAutoBinding(true);
var pq2 = des.prepare(queryDefinition2);
var qr2 = pq2.execute(null);
var ri2 = qr2.getResultIterator( );
var cc = ri2.getResultMetaData().getColumnCount();
System.out.println("col_01_name: " +
ri2.getResultMetaData().getColumnLabel(1));
System.out.println("Count: " + cc);
while (ri2.next()) {
System.out.println("Table: "+ ri2);
System.out.println("col_01: "+ ri2.getValue("col_01"));
}
ri.close();
qr.close();
ri2.close();
qr2.close();
des.close();
I managed to make the code work. Following lines solved the problem with second query:
var des2 = DataRequestSession.newSession(myconfig, new DataSessionContext(3));
des2.defineDataSource(des2.getModelAdaptor()
.adaptDataSource(reportContext.getDesig nHandle()
.findDataSource("mydb")));
des2.defineDataSet(des2.getModelAdaptor()
.adaptDataSet(reportContext.getDesignHandle()
.findDataSet("tableName")));
and then:
var pq2 = des2.prepare(queryDefinition2);
Also we have changed the function to return the query instead of creating a temporary table.
I am using Npgsql for postgresql in C++/CLI. So, the problem is, I have a db on my computer, and I am trying to select some of data from it's "movies" table. I already entered some data inside it, so I know that it has some data. But when I try to select some of them, answer to my query is empty. My code is like below:
public: string* SelectData(string* torrent)
{
conn->Open();
String ^ query = "SELECT title, director, actors, genre FROM movies";
Npgsql::NpgsqlCommand ^ command = gcnew NpgsqlCommand(query, conn);
try{
Npgsql::NpgsqlDataReader ^ dr = command->ExecuteReader();
for (int i = 0; i < N_TORRENT; i++)
{
if(dr->Read())
{
string std1 = toStandardString((String^)dr[0]);
string std2 = toStandardString((String^)dr[1]);
string std3 = toStandardString((String^)dr[2]);
string std4 = toStandardString((String^)dr[3]);
torrent[i] = std1 + " " + std2 + " " + std3 + " " + std4;
}
}
return torrent;
}
finally{
conn->Close();
}
}
(For the ones who will look for this question's answer)
Problem solved when I changed my query and look for the "title" column that are not empty. But this is ridiculus, so I beleive the problem was about pgAdmin. Because my insert query was not working either, but I added "rowseffected" variable and it shows the effected row's number and looks like it is working. So the problem is probably about the pgAdmin.
i have some methods like:
public static string ToOtherFormat (this string inp)
{
// some code to change inp
return inp;
}
and in my select i want to have code like this:
var DetailMembers = db.TB_Members
.Where(x=> x.FName == obj.ToOtherFormat())
.Select( x=> new { name = (x.FName.ToOtherFormat() + " " + x.LName) , x.ActCode });
i try and just have error. is it possible?
thanks!
i receive this error in simple convert to integer
LINQ to Entities does not recognize the method 'Int32 ToInt32(System.String)' method, and this method cannot be translated into a store expression.
with this code
.Where(x => x.MemberID == Convert.ToInt32(Hmemid.Hash_two_Decrypt())
Looks like you are querying against the database. Your current query will get translated into SQL query and since SQL doesn't recognize your function that is why you get error.
You may get the data from the tables using a query without that function and then later do the formatting on the result set.
i found it on use .AsEnumerable() method like:
var DetailMembers = db.TB_Members.AsEnumerable()
.Where(x=> x.FName == obj.ToOtherFormat())
.Select( x=> new { name = (x.FName.ToOtherFormat() + " " + x.LName) , x.ActCode });