How do i check if my Linq query produced any result? - c#

Hi guys I am using entity framework, I am facing some problem while checking if my linq returned any results, if it returns any result I want to use it as a data source, the following is the code please have a look:
var dbContext = new DBEntities();
try
{
var linQuery = from cq in dbContext.tblCharacteristics
where cq.CharacteristicID.Equals(combobox1.SelectedText)
select new
{
CharacteristicIDs = cq.CharID,
CharacteristicNames = cq.CharName
};
if (linQuery.Any()) //Also tried with linQuery.Count() != 0
{
lbChaKeyValues.DataSource = linQuery;
lbChaKeyValues.DisplayMember = "CharacteristicNames";
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
dbContext.Dispose();
}
I am getting following error : "DbComparisonExpression requires arguments with comparable types."

IF CharacteristicID is an integer type, the comparison won't work. Instead try
var inputFromUser = Int32.Parse( combobox1.SelectedText );
var linQuery = from cq in dbContext.tblCharacteristics
where cq.CharacteristicID == inputFromUser
select new
{
CharacteristicIDs = cq.CharID,
CharacteristicNames = cq.CharName
};
Incidentally .Any() is the correct way to test for search results. And if you're not going to use the return results, there's no need to project the data into an anonymous type. Just use select true or select cq which allows the optimizer to use the best index in the DB.

Related

How to get the entire list instead of only the first result? Net Core 3.1

The following functions return only the first row of the database, would you please guide me get the entire rows please?
My Function :
private List<Phrases_Clp> PhrasesStringToListPhrases_Clp(string phrases_codes)
{
List<Phrases_Clp> phrases_Clps = new List<Phrases_Clp>();
if (!String.IsNullOrEmpty(phrases_codes))
{
if (phrases_codes.Contains(","))
{
string[] listprhases = phrases_codes.Split(",");
foreach (var item in listprhases)
{
var mentiontoinsert = _context.Phrases_Clps.FirstOrDefault(m =>
m.Phrase_Numero == item);
phrases_Clps.Add(mentiontoinsert);
}
}
else
{
var mentiontoinsert = _context.Phrases_Clps.FirstOrDefault(m =>
m.Phrase_Numero == phrases_codes);
phrases_Clps.Add(mentiontoinsert);
}
}
return phrases_Clps;
}
UPDATE :
It still gives me the first result. I wonder if I should do changes in my view as I display information from another table which correspond the cell values in the current table.
Table Identification_Produit
Table Phrases Clp
Current Output:
Desired Output is to display 'Mentions Dangers' of each Product.
GET:
//GET: EvaluationRisque/Create
[Authorize(Roles = "Administrateur, Modificateur")]
public async Task<IActionResult> Create()
{
List<Models.dbo.equipements_protection.Equipement_Protection> listsequipement = _context.Equipement_Protections.ToList();
Create_Viewbags();
var model = new EvaluationRisquesViewModel();
var produitUtiliseByProduitId = await _context.Identification_Produit.FirstOrDefaultAsync();
model.MentionsDanger = produitUtiliseByProduitId;
model.List_Mentions_Danger = PhrasesStringToListPhrases_Clp(model.MentionsDanger.Mentions_Danger);
return View(model);
}
Bootstrap Model in the View Page:
<td>#foreach (var mention_danger in Model.List_Mentions_Danger)
{
<p> #mention_danger.Phrase_Numero : #mention_danger.Phrase_Libelle
</p>}
</td>
Change FirstOrDefault(...) to .Where(...).ToList() (or use phrases_Clps.AddRange( _context.Phrases_Clps.Where(...))).
But actually there is no need to make multiple requests to the database and you can skip conditional splitting, so something like following should work:
List<Phrases_Clp> phrases_Clps = null;
if (!string.IsNullOrEmpty(phrases_codes))
{
string[] listprhases = phrases_codes.Split(","); // will be array with one item if there are no commas in string
phrases_Clps = _context.Phrases_Clps
.Where(m => listprhases.Contains(m.Phrase_Numero))
.ToList();
}
return phrases_Clps ?? new List<Phrases_Clp>();
Because you are using FirstOrDefault function in this line:
var mentiontoinsert = _context.Phrases_Clps.FirstOrDefault(m => m.Phrase_Numero == item);
replace it with Where function.
Thinking that to utilize the query as IQueryable.
Updated:
Thanks for #GuruStron (Guru/Sensei)'s opinion and for pointing out the issue from my previous answer.
In short,
Exit the function with an empty List if phrases_codes is an empty string or null.
Working with IQueryable to prepare the different search criteria and defer the execution.
Once the query is prepared, execute the query via .ToList().
if (String.IsNullOrEmpty(phrases_codes))
return new List<Phrases_Clp>();
IQueryable<Phrases_Clp> query = _context.Phrases_Clps;
if (phrases_codes.Contains(","))
{
string[] listprhases = phrases_codes.Split(",");
query = query
.Where(x => listprhases.Contains(x.Phrase_Numero));
}
else
{
query = query
.Where(x => x.Phrase_Numero == phrases_codes);
}
return query.ToList();
This is my minimalist proposal
private List<Phrases_Clp> PhrasesStringToListPhrases_Clp(string phrases_codes)
{
var listprhases = phrases_codes != null ? phrases_codes.Split(",") : new string[0];
return _context.Phrases_Clps.Where(x => listprhases.Contains(x.Phrase_Numero)).ToList();
}

How to convert SQLQuery to SortedList through EF6

I have an Entity Framework 6 class called Materials, which is reflected in my database as a table with the same name. Using a parent parameter, I need to return a sorted list of materials from a SQL Query, so that I can later check that edits the user makes do not affect the order. My SQL is a stored procedure that looks like this:
CREATE PROC [dbo].[GET_SortedMaterials](#FinishedGoodCode VARCHAR(50))
AS
SELECT
ROW_NUMBER() OVER (ORDER BY Component.Percentage_of_Parent DESC,Material.Material) AS _sortField
,Material.*
FROM
Components AS Component
INNER JOIN Materials AS Material ON Component.Child_Material = Material.Material
WHERE
Component.Parent_Code = #FinishedGoodCode
ORDER BY
Component.Percentage_of_Parent DESC
,Material.Material
As you can see, the orderby field is not included in the Material. For this reason, I felt I could not return just a set of Material objects and still keep the sorting - I have performed the ordering in SQL and added the _sortField (I think that field may be a bad idea).
My C# code to read the SQL looks like this:
public async Task<SortedList<int, Materials>> GET_SortedMaterials(IProgress<Report> progress, string finishedGoodCode)
{
try
{
var report = new Report { Message = "Retrieving Sorted Materials", NewLine = true, StatusCode = Enums.StatusCode.Working };
progress.Report(report);
using (var context = new DBContext())
{
var ingredientList = await context.Database.SqlQuery<(int _sortField,Materials mat)>("[app].[GET_Customers]").ToListAsync();
var sorted = new SortedList<int, Raw_Materials>();
foreach (var (_sortField, mat) in ingredientList.OrderBy(x=>x._sortField))
{
sorted.Add(_sortField, mat);
}
return sorted;
}
}
catch (Exception ex)
{ [EXCLUDED CODE]
}
}
When the code executes, I get the correct number of rows returned, but I do not get a Sorted list where the Key corresponds to the _sortField value and the Value to the Material value. I have tried various different versions of basically the same code and I cannot get the script to return a list of materials with information about their sorting, instead, the conversion to EF class fails entirely and I only get null values back:
Any advice about how to return a sorted list from SQL and maintain the sorting in C#, when the sort field is not in the return values would be very gratefully received.
use
var ingredientList = await context.Database.SqlQuery<Materials>("[app].[GET_Customers]").Select((mat, _sortField) => (_sortField, mat)).ToDictionary(x => x._sortField, x => x.mat);
or if you want async load use
var ingredientList = await context.Database.SqlQuery<Materials>("[app].[GET_Customers]").ToListAsync().Result.Select((mat, _sortField) => (_sortField, mat)).ToDictionary(x => x._sortField, x => x.mat);
full code
public async Task<SortedList<int, Materials>> GET_SortedMaterials(IProgress<Report> progress, string finishedGoodCode)
{
try
{
var report = new Report { Message = "Retrieving Sorted Materials", NewLine = true, StatusCode = Enums.StatusCode.Working };
progress.Report(report);
using (var context = new DBContext())
{
var ingredientList = await context.Database.SqlQuery<Materials>("[app].[GET_Customers]").ToListAsync().Result.Select((mat, _sortField) => (_sortField, mat)).ToDictionary(x => x._sortField, x => x.mat);
var sorted = new SortedList<int, Raw_Materials>();
foreach (var item in ingredientList.OrderBy(x => x.Key))
{
sorted.Add(item.Key, item.Value);
}
return sorted;
}
}
catch (Exception ex)
{
[EXCLUDED CODE]
}
}

Using Linq query syntax to search XML datatype column using Entity Framework in C#

I'm trying to build a function to query a table that uses a column of type XML.
This is my code:
public int GetTotalQueue(string queueCode)
{
int queueNumber = 0;
QueueEntities _context = new QueueEntities();
try
{
var data = (from a in _context.QueueTable
where a.QueueStatusId == 5
&& a.Workgroup == "Group H"
&& a.ExtraData.Cast<string>().Contains<string>(queueCode)
select a.QueueId).Count();
queueNumber = data;
}
catch (Exception ex)
{
ExceptionHandler(ex);
throw;
}
return queueNumber;
}
Extra data is the XML type column. I tried casting it to a string to do a contains but when I try to actually run this method in the wcf tester the service just fails with a non descriptive internal error. Does anyone have any suggestions on what I can do to fix this query? Am I messing up my cast? Any help would be appreciated. Thanks!

My first try at converting from LINQ to SQL to LINQ to Entity

The program does some very simple lookups to generate data for a flashcard program which supports Mandarin Chinese and English
I deleted the .dbml file and created a Linq to Entities instead.
The original lookup was this:
using (var ceDictionary = new CeDictDataContext(Properties.Settings.Default.ChineseStudyConnection))
{
var definitions = from ed in ceDictionary.CeDicts
where ed.Char == WorkTraditional.Text
where ed.Bopo == foundBo[0]
select ed;
try
{
foreach (var definition in definitions)
{
textDefinition.Text = definition.English;
break;
}
}
catch (System.Data.StrongTypingException eng)
{
Status.Text = eng.Message;
textDefinition.Text = #"DBNull";
}
}
After a bit of head scratching and documentation browsing, I decided I only need to update the using statement and change the 'select ed' to a 'select new'
Like this:
using (var ceDictionary = new ChineseStudyEntities())
{
var definitions = from ed in ceDictionary.CeDicts
where ed.Char == WorkTraditional.Text
where ed.Bopo == foundBo[0]
select new
{
ed.English
};
try
{
foreach (var definition in definitions)
{
textDefinition.Text = definition.English;
break;
}
}
catch (System.Data.StrongTypingException eng)
{
Status.Text = eng.Message;
textDefinition.Text = #"DBNull";
}
}
The good news is: the compiler was happy and the project builds without errors.
The bad news is: the foreach statement crashes at runtime with this (unintelligible to me) error message: Message=LINQ to Entities does not recognize the method 'System.String get_Item(Int32)' method, and this method cannot be translated into a store expression.
It is unintelligible because the one column I'm pulling out of the database is a string and I cannot begin to guess why "get_Item(Int32)" is somehow involved. (The two columns in the 'where' clauses are also strings.)
I think that your problem is with this part: foundBo[0]. Accessing letters by index cannot be translated to common SQL.
Try using Substring instead:
var definitions = from ed in ceDictionary.CeDicts
where ed.Char == WorkTraditional.Text
where ed.Bopo == foundBo.Substring(0, 1)
select ed;
LINQ to SQL cant translate expressionfoundBo[0] to SQL, copy it to variable:
var temp = foundBo[0];
var definitions = from ed in ceDictionary.CeDicts
where ed.Char == WorkTraditional.Text
where ed.Bopo == temp
select ed;

Lucene.NET and searching on multiple fields with specific values

I've created an index with various bits of data for each document I've added, each document can differ in it field name.
Later on, when I come to search the index I need to query it with exact field/ values - for example:
FieldName1 = X AND FieldName2 = Y AND FieldName3 = Z
What's the best way of constructing the following using Lucene .NET:
What analyser is best to use for this exact match type?
Upon retrieving a match, I only need one specific field to be returned (which I add to each document) - should this be the only one stored?
Later on I'll need to support keyword searching (so a field can have a list of values and I'll need to do a partial match).
The fields and values come from a Dictionary<string, string>. It's not user input, it's constructed from code.
Thanks,
Kieron
Well, I figured it out eventually - here's my take on it (this could be completely wrong, but it works for):
public Guid? Find (Dictionary<string, string> searchTerms)
{
if (searchTerms == null)
throw new ArgumentNullException ("searchTerms");
try
{
var directory = FSDirectory.Open (new DirectoryInfo (IndexRoot));
if (!IndexReader.IndexExists (directory))
return null;
var mainQuery = new BooleanQuery ();
foreach (var pair in searchTerms)
{
var parser = new QueryParser (
Lucene.Net.Util.Version.LUCENE_CURRENT, pair.Key, GetAnalyzer ());
var query = parser.Parse (pair.Value);
mainQuery.Add (query, BooleanClause.Occur.MUST);
}
var searcher = new IndexSearcher (directory, true);
try
{
var results = searcher.Search (mainQuery, (Filter)null, 10);
if (results.totalHits != 1)
return null;
return Guid.Parse (searcher.Doc (results.scoreDocs[0].doc).Get (ContentIdKey));
}
catch
{
throw;
}
finally
{
if (searcher != null)
searcher.Close ();
}
}
catch
{
throw;
}
}

Categories

Resources