WPF application Linq to sql getting data - sql

I'm making a WPF application with a datagrid that displays some sql data.
Now i'm making a search field but that doesn't seem to work:
Contactpersoon is an nvarchar
bedrijf is an nvarchar
but
LeverancierPK is an INT
How can I combinate that in my search?
If i convert LeverancierPK to string, then I can use Contains but that gives me an error
//Inisiatie
PRCEntities vPRCEntities = new PRCEntities();
var vFound = from a in vPRCEntities.tblLeveranciers
where ((((a.LeverancierPK).ToString()).Contains(vWoord)) ||
(a.Contactpersoon.Contains(vWoord)) ||
(a.Bedrijf.Contains(vWoord)))
orderby a.LeverancierPK
select a;
myDataGrid_Leveranciers.ItemsSource = vFound;
Thanks

If you don't care about pulling all records back from the DB (which in your answer you pulled everything back), then you can just do a .ToList() before the where clause.
var vFound = vPRCEntities.tblLeveranciers.ToList()
.Where(a => a.LeverancierPK.ToString().Contains(vWoord)) ||
a.Contactpersoon.Contains(vWoord) ||
a.Bedrijf.Contains(vWoord))
.OrderBy(a.LeverancierPK);

This code can do what I was looking for but I think it could be alot shorter.
PRCEntities vPRCEntities = new PRCEntities();
var vFound = from a in vPRCEntities.tblLeveranciers
orderby a.LeverancierPK
select a;
myDataGrid_Leveranciers.ItemsSource = null;
myDataGrid_Leveranciers.Items.Clear();
foreach (var item in vFound)
{
if (item.Bedrijf.Contains(vWoord))
{
myDataGrid_Leveranciers.Items.Add(item);
}
else
{
if (item.LeverancierPK.ToString().Contains(vWoord))
{
myDataGrid_Leveranciers.Items.Add(item);
}
else
{
if (item.Contactpersoon != null)
{
if (item.Contactpersoon.Contains(vWoord))
{
myDataGrid_Leveranciers.Items.Add(item);
}
}
}
}
}

Related

MVC Entity Framework, Query returns null

Hi guys can you help me understand why i keep getting a null instead of get the value.
Need to receive the saidaservicoid to be able to update. I receive the value from the view but can't update elemento. Stays null.
Thanks in advance for the help.
[Database]
[elementoRepository]
public async Task UpdateElementoSaidaServicosAsync(AddSaidasServicoViewModel model)
{
var saidaServico = await _context.SaidaServicos.FindAsync(model.SaidaServicoId);
var elemento = await _context.Elementos.FindAsync(model.ElementoId);
if (elemento == null)
{
return;
}
var updateElementoSaida = _context.Elementos.Where(e => e.Id == model.ElementoId).FirstOrDefault();
if (updateElementoSaida == null)
{
updateElementoSaida = new Elemento
{
saidaServico = saidaServico,
};
_context.Elementos.Update(updateElementoSaida);
}
else
{
int SaidaServicos = model.SaidaServicoId;
updateElementoSaida.saidaServico = saidaServico;
}
await _context.SaveChangesAsync();
return;
}
Ok. the best way that i found to solve this issue was to get the last ID.
int SaidaServicos = _context.SaidaServicos.Max(item => item.Id);

working with option of $query in yii2

i want use where for $query.
foreach ($oppId as $o) {
$id = $o['opportunity_id'];
$query->Where("id=$id");
}
When I use this. All items shown
$query->orWhere("id=$id");
i need get this query :
SELECT * FROM `opportunity` WHERE id =27 or id =28
this is all of my function :
public function actionShow($type = 0, $city = 0, $client = 0) {
$query = (new \yii\db\Query())->select(['*'])->from('opportunity ')->innerJoin('profile_details', 'opportunity.user_id=profile_details.user_id')->orderBy('id desc');
$query->Where('id !=-1');
if (isset($_REQUEST['type'])) {
$type = $_REQUEST['type'];
if ($type != 0) {
$query->andWhere("project_type_id=$type");
}
}
if (isset($_REQUEST['city'])) {
$city = $_REQUEST['city'];
if ($city != 0) {
$query->andWhere("state_id=$city");
}
}
if (isset($_REQUEST['client'])) {
$client = $_REQUEST['client'];
if ($client != 0) {
$oppId = \app\models\OpportunityControl::find()
->where('project_type_id = :project_type_id', [':project_type_id' => $client])
->all();
foreach ($oppId as $o) {
$id = $o['opportunity_id'];
$query->orWhere("id=$id");
}
}
}
You very much do not want to use strings to add to the query under any circumstances as that is ripe for SQL injection. I'd format it like this:
...
$params = [];
foreach ($oppId as $o) {
$params[] = $o->opportunity_id;
}
$query->andWhere(['in', 'id', $params]);
...
You should also adjust your other query params so that you are not passing variables into SQL via a string.
if (isset($_REQUEST['type'])) {
$type = $_REQUEST['type'];
if ($type != 0) {
$query->andWhere(['project_type_id' => $type]);
}
}
if (isset($_REQUEST['city'])) {
$city = $_REQUEST['city'];
if ($city != 0) {
$query->andWhere(['state_id' => $city]);
}
}
See the Yii2 guide on using variables in queries for what you are trying to avoid here. Specifically:
Do NOT embed variables directly in the condition like the following, especially if the variable values come from end user inputs, because this will make your application subject to SQL injection attacks.
// Dangerous! Do NOT do this unless you are very certain $status must be an integer.
$query->where("status=$status");
I do it with Arrays
$query->where(['or',['id'=>27],['id'=>28]]);
But in your case save all ids in a Array is not possible,I do it with string inside foreach
$StringWhere='';
$LastElement = end($oppId);
foreach ($oppId as $o)
{
$id = $o['opportunity_id'];
$StringWhere.=' id='.$id;
if($o!=$LastElement)
{
$StringWhere.=' or ';
}
}
$query->where($StringWhere);
$query->where(['or',['id'=>27],['id'=>28]]);
I use this and it works perfectly as mentioned by metola. :)

Google BigQuery returns only partial table data with C# application using .net Client Library

I am trying to execute the query (Basic select statement with 10 fields). My table contains more than 500k rows. C# application returns the response with only 4260 rows. However Web UI returns all the records.
Why my code returns only partial data, What is the best way to select all the records and load into C# Data Table? If there is any code snippet it would be more helpful to me.
using Google.Apis.Auth.OAuth2;
using System.IO;
using System.Threading;
using Google.Apis.Bigquery.v2;
using Google.Apis.Bigquery.v2.Data;
using System.Data;
using Google.Apis.Services;
using System;
using System.Security.Cryptography.X509Certificates;
namespace GoogleBigQuery
{
public class Class1
{
private static void Main()
{
try
{
Console.WriteLine("Start Time: {0}", DateTime.Now.ToString());
String serviceAccountEmail = "SERVICE ACCOUNT EMAIL";
var certificate = new X509Certificate2(#"KeyFile.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { BigqueryService.Scope.Bigquery, BigqueryService.Scope.BigqueryInsertdata, BigqueryService.Scope.CloudPlatform, BigqueryService.Scope.DevstorageFullControl }
}.FromCertificate(certificate));
BigqueryService Service = new BigqueryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "PROJECT NAME"
});
string query = "SELECT * FROM [publicdata:samples.shakespeare]";
JobsResource j = Service.Jobs;
QueryRequest qr = new QueryRequest();
string ProjectID = "PROJECT ID";
qr.Query = query;
qr.MaxResults = Int32.MaxValue;
qr.TimeoutMs = Int32.MaxValue;
DataTable DT = new DataTable();
int i = 0;
QueryResponse response = j.Query(qr, ProjectID).Execute();
string pageToken = null;
if (response.JobComplete == true)
{
if (response != null)
{
int colCount = response.Schema.Fields.Count;
if (DT == null)
DT = new DataTable();
if (DT.Columns.Count == 0)
{
foreach (var Column in response.Schema.Fields)
{
DT.Columns.Add(Column.Name);
}
}
pageToken = response.PageToken;
if (response.Rows != null)
{
foreach (TableRow row in response.Rows)
{
DataRow dr = DT.NewRow();
for (i = 0; i < colCount; i++)
{
dr[i] = row.F[i].V;
}
DT.Rows.Add(dr);
}
}
Console.WriteLine("No of Records are Readed: {0} # {1}", DT.Rows.Count.ToString(), DateTime.Now.ToString());
while (true)
{
int StartIndexForQuery = DT.Rows.Count;
Google.Apis.Bigquery.v2.JobsResource.GetQueryResultsRequest SubQR = Service.Jobs.GetQueryResults(response.JobReference.ProjectId, response.JobReference.JobId);
SubQR.StartIndex = (ulong)StartIndexForQuery;
//SubQR.MaxResults = Int32.MaxValue;
GetQueryResultsResponse QueryResultResponse = SubQR.Execute();
if (QueryResultResponse != null)
{
if (QueryResultResponse.Rows != null)
{
foreach (TableRow row in QueryResultResponse.Rows)
{
DataRow dr = DT.NewRow();
for (i = 0; i < colCount; i++)
{
dr[i] = row.F[i].V;
}
DT.Rows.Add(dr);
}
}
Console.WriteLine("No of Records are Readed: {0} # {1}", DT.Rows.Count.ToString(), DateTime.Now.ToString());
if (null == QueryResultResponse.PageToken)
{
break;
}
}
else
{
break;
}
}
}
else
{
Console.WriteLine("Response is null");
}
}
int TotalCount = 0;
if (DT != null && DT.Rows.Count > 0)
{
TotalCount = DT.Rows.Count;
}
else
{
TotalCount = 0;
}
Console.WriteLine("End Time: {0}", DateTime.Now.ToString());
Console.WriteLine("No. of records readed from google bigquery service: " + TotalCount.ToString());
}
catch (Exception e)
{
Console.WriteLine("Error Occurred: " + e.Message);
}
Console.ReadLine();
}
}
}
In this Sample Query get the results from public data set, In table contains 164656 rows but response returns 85000 rows only for the first time, then query again to get the second set of results. (But not known this is the only solution to get all the results).
In this sample contains only 4 fields, even-though it does not return all rows, in my case table contains more than 15 fields, I get response of ~4000 rows out of ~10k rows, I need to query again and again to get the remaining results for selecting 1000 rows takes time up to 2 minutes in my methodology so I am expecting best way to select all the records within single response.
Answer from User #:Pentium10
There is no way to run a query and select a large response in a single shot. You can either paginate the results, or if you can create a job to export to files, then use the files generated in your app. Exporting is free.
Step to run a large query and export results to files stored on GCS:
1) Set allowLargeResults to true in your job configuration. You must also specify a destination table with the allowLargeResults flag.
Example:
"configuration":
{
"query":
{
"allowLargeResults": true,
"query": "select uid from [project:dataset.table]"
"destinationTable": [project:dataset.table]
}
}
2) Now your data is in a destination table you set. You need to create a new job, and set the export property to be able to export the table to file(s). Exporting is free, but you need to have Google Cloud Storage activated to put the resulting files there.
3) In the end you download your large files from GCS.
It my turn to design the solution for better results.
Hoping this might help someone. One could retrieve next set of paginated result using PageToken. Here is the sample code for how to use PageToken. Although, I liked the idea of exporting for free. Here, I write rows to flat file but you could add them to your DataTable. Obviously, it is a bad idea to keep large DataTable in memory though.
public void ExecuteSQL(BigqueryService bqservice, String ProjectID)
{
string sSql = "SELECT r.Dealname, r.poolnumber, r.loanid FROM [MBS_Dataset.tblRemitData] R left join each [MBS_Dataset.tblOrigData] o on R.Dealname = o.Dealname and R.Poolnumber = o.Poolnumber and R.LoanID = o.LoanID Order by o.Dealname, o.poolnumber, o.loanid limit 100000";
QueryRequest _r = new QueryRequest();
_r.Query = sSql;
QueryResponse _qr = bqservice.Jobs.Query(_r, ProjectID).Execute();
string pageToken = null;
if (_qr.JobComplete != true)
{
//job not finished yet! expecting more data
while (true)
{
var resultReq = bqservice.Jobs.GetQueryResults(_qr.JobReference.ProjectId, _qr.JobReference.JobId);
resultReq.PageToken = pageToken;
var result = resultReq.Execute();
if (result.JobComplete == true)
{
WriteRows(result.Rows, result.Schema.Fields);
pageToken = result.PageToken;
if (pageToken == null)
break;
}
}
}
else
{
List<string> _fieldNames = _qr.Schema.Fields.ToList().Select(x => x.Name).ToList();
WriteRows(_qr.Rows, _qr.Schema.Fields);
}
}
The Web UI automatically flattens the data. This means that you see multiple rows for each nested field.
When you run the same query via the API, it won't be flattened, and you get fewer rows, as the nested fields are returned as objects. You should check if this is the case at you.
The other is that indeed you need to paginate through the results. Paging through list results has this explained.
If you want to do only one job, than you should write your query ouput to a table, than export the table as JSON, and download the export from GCS.

NHibernate named query and multiple result sets

We have a stored procedure that returns several tables. When calling it using NHibernate, we use the bean transformer but only get the first table transformed and all other results are ignored.
I know that NH is able to process several queries in one db trip using futures but we only have one query and it produces a result that is similar to what we would get with futures, but getting this from a stored procedure.
I believe this scenario is quite common but could not find any clues. Is it possible to use NH to retrieve such results?
Yes,you can use MultiQuery "Hack" like this:
The procudure:
CREATE PROCEDURE [dbo].[proc_Name]
AS BEGIN
SELECT * FROM Question
SELECT * FROM Question
END
The NHibernate Query Code:
public void ProcdureMultiTableQuery()
{
var session = Session;
var procSQLQuery = session.CreateSQLQuery("exec [proc_Name] ?,?");// prcodure returns two table
procSQLQuery.SetParameter(0, userId);
procSQLQuery.SetParameter(1, page);
procSQLQuery.AddEntity(typeof(Question));
var multiResults = session.CreateMultiQuery()
.Add(procSQLQuery)
// More table your procedure returns,more empty SQL query you should add
.Add(session.CreateSQLQuery(" ").AddEntity(typeof(Question))) // the second table returns Question Model
.List();
if (multiResults == null || multiResults.Count == 0)
{
return;
}
if (multiResults.Count != 2)
{
return;
}
var questions1 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[0]);
var questions2 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[1]);
}
static T[] ConvertObjectsToArray<T>(System.Collections.IList objects)
{
if (objects == null || objects.Count == 0)
{
return null;
}
var array = new T[objects.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = (T)objects[i];
}
return array;
}

How to append sql to Entity Framework query

How to append raw sql e.g. condition to entity framework linq query?
I'm open to all suggestions so it's not mandatory to append it to linq query main point is to e.g. filter by adding some custom sql to query overall.
Using IQueryable we can append the condition on the Linq to entity query.
private IQueryable<Customer> FilterList(IQueryable<Customer> customer, List<string> filter, string filterValue)
{
IQueryable<Customer> query = new List<Customer>().AsQueryable();
if (filter == null || string.IsNullOrEmpty(filterValue))
{
return customer;
}
var filterLower = filter.First().ToLower();
filterValue = filterValue.ToLower();
if (filterLower.Contains("retail") || (filterLower.Contains("distributor"))
{
return customer.Where(x => (!string.IsNullOrEmpty(x.Retail) && x.Retail.Contains(filterValue)) || (!string.IsNullOrEmpty(x.Distributor) && x.Distributor.Contains(filterValue)));
}
if (filterLower.Contains("retail"))
{
query = customer.Where( x=> !string.IsNullOrEmpty(x.Distributor) && x.Distributor.Contains(filterValue));
}
if (filterLower.Contains("distributor"))
{
query = customer.Where(x => !string.IsNullOrEmpty(x.Retail) && x.Retail.Contains(filterValue)).Union(query);
}
return query;
}