how to write LINQ Query on three columns with a different value on each one - linq

I'm new to this and this is my first question.
So far I have this, but it takes a long time to get the record:
public string BuscarPedimento(string patente, string pedimento2, string aduana)
{
using (var context = new DataStage3Context())
{
DsPedimentos pedimento = context.DsPedimentos.FirstOrDefault(p => (p.Patente == patente & p.AduanaDespacho == aduana & p.Pedimento == pedimento2));
if (pedimento == null)
return "";
else
return Convert.ToString(pedimento.Id);
}
}

Related

How to get all items with the same value in list of lists c# LINQ?

I have a to add a specific requirement in a piece of code already implemented.
The data structure is something of this sort:
public class Module
{
public string Type;
public string ID;
public List<Point> Points = new List<Point>();
}
public class Point
{
public string Type;
public string Location;
public string Connection;
}
Originally LINQ was used to return all modules which certain characteristics
List<Module> miList = Modules.Where(m => m.Type != null
&& m.ID == "A"
&& m.Points.Where(t => t.Connection == ""
&& SimilarPoint(t.Type, x).ToList())
.Count() > 0)
.ToList();
with x an input to the function. The new requirement dictates that the modules returned shall all have points with Connection equal to "" and the same value in the Location field.
It seemed to me that the SelectMany could be used to this end, but I am not getting what I expected.
How should the function above be modified?
Thanks in advance
Not exactly sure what the SimilarPoint(t.Type, x) does here.
May be you should try something like this and find out if it works for you -
var resultSet = Modules.Where(m => !string.IsNullOrEmpty(m.Type) && m.ID.Equals("A"))
.Select(n =>
new Module {
Type=n.Type,
ID=n.ID,
Points= n.Points.Where(p => String.IsNullOrEmpty(p.Connection) && String.IsNullOrEmpty(p.Location)).ToList()
})
.ToList();
You said all the returned modules have the same Location, but that doesn't explain how you select which Location so I arbitrarily picked the first matching module's location:
var miQuery1 = Modules.Where(m => m.Type != null
&& m.ID == "A"
&& m.Points.Where(t => t.Connection == ""
&& SimilarPoint(t.Type, x).ToList()).Count() > 0)
.Where(m => m.Points.All(p => p.Connection == ""));
var miQuery2 = miQuery1.Where(m => m.Location == miQuery1.First().Location);
List<Module> miList = miQuery2.ToList();

Why can't I compare two fields in a search predicate in Sitecore 7.5?

I am trying to build a search predicate in code that compares two fields in Sitecore and I am getting a strange error message. Basically I have two date fields on each content item - FirstPublishDate (the date that the content item was first published) and LastPublishDate (the last date that the content item was published). I would like to find all content items where the LastPublishDate falls within a certain date range AND where the LastPublishDate does not equal the FirstPublishDate. Using Linq here is my method for generating the predicate...
protected Expression<Func<T, Boolean>> getDateFacetPredicate<T>() where T : MySearchResultItem
{
var predicate = PredicateBuilder.True<T>();
foreach (var facet in myFacetCategories)
{
var dateTo = System.DateTime.Now;
var dateFrom = dateTo.AddDays(facet.Value*-1);
predicate = predicate.And(i => i.LastPublishDate.Between(dateFrom, dateTo, Inclusion.Both)).And(j => j.LastPublishDate != j.FirstPublishDate);
}
return predicate;
}
Then I use this predicate in my general site search code to perform the search as follows: the above predicate gets passed in to this method as the "additionalWhere" parameter.
public static SearchResults<T> GeneralSearch<T>(string searchText, ISearchIndex index, int currentPage = 0, int pageSize = 20, string language = "", IEnumerable<string> additionalFields = null,
Expression<Func<T, Boolean>> additionalWhere = null, Expression<Func<T, Boolean>> additionalFilter = null, IEnumerable<string> facets = null,
Expression<Func<T, Boolean>> facetFilter = null, string sortField = null, SortDirection sortDirection = SortDirection.Ascending) where T : SearchResultItem {
using (var context = index.CreateSearchContext()) {
var query = context.GetQueryable<T>();
if (!string.IsNullOrWhiteSpace(searchText)) {
var keywordPred = PredicateBuilder.True<T>();
// take into account escaping of special characters and working around Sitecore limitation with Contains and Equals methods
var isSpecialMatch = Regex.IsMatch(searchText, "[" + specialSOLRChars + "]");
if (isSpecialMatch) {
var wildcardText = string.Format("\"*{0}*\"", Regex.Replace(searchText, "([" + specialSOLRChars + "])", #"\$1"));
wildcardText = wildcardText.Replace(" ", "*");
keywordPred = keywordPred.Or(i => i.Content.MatchWildcard(wildcardText)).Or(i => i.Name.MatchWildcard(wildcardText));
}
else {
keywordPred = keywordPred.Or(i => i.Content.Contains(searchText)).Or(i => i.Name.Contains(searchText));
}
if (additionalFields != null && additionalFields.Any()) {
keywordPred = additionalFields.Aggregate(keywordPred, (current, field) => current.Or(i => i[field].Equals(searchText)));
}
//query = query.Where(i => (i.Content.Contains(searchText) || i.Name.Contains(searchText))); // more explicit call to check the content or item name for our term
query = query.Where(keywordPred);
}
if (language == string.Empty) {
language = Sitecore.Context.Language.ToString();
}
if (language != null) {
query = query.Filter(i => i.Language.Equals(language));
}
query = query.Page(currentPage, pageSize);
if (additionalWhere != null) {
query = query.Where(additionalWhere);
}
if (additionalFilter != null) {
query = query.Filter(additionalFilter);
}
query = query.ApplySecurityFilter();
FacetResults resultFacets = null;
if (facets != null && facets.Any()) {
resultFacets = facets.Aggregate(query, (current, fname) => current.FacetOn(i => i[fname])).GetFacets();
}
// calling this before applying facetFilter should allow us to get a total facet set
// instead of just those related to the current result set
// var resultFacets = query.GetFacets();
// apply after getting facets for more complete facet list
if (facetFilter != null) {
query = query.Where(facetFilter);
}
if (sortField != null)
{
if (sortDirection == SortDirection.Ascending)
{
query = query.OrderBy(x => x[sortField]);
}
else
{
query = query.OrderByDescending(x => x[sortField]);
}
}
var results = query.GetResults(); // this enumerates the actual results
return new SearchResults<T>(results.Hits, results.TotalSearchResults, resultFacets);
}
}
When I try this I get the following error message:
Server Error in '/' Application.
No constant node in query node of type: 'Sitecore.ContentSearch.Linq.Nodes.EqualNode'. Left: 'Sitecore.ContentSearch.Linq.Nodes.FieldNode'. Right: 'Sitecore.ContentSearch.Linq.Nodes.FieldNode'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NotSupportedException: No constant node in query node of type: 'Sitecore.ContentSearch.Linq.Nodes.EqualNode'. Left: 'Sitecore.ContentSearch.Linq.Nodes.FieldNode'. Right: 'Sitecore.ContentSearch.Linq.Nodes.FieldNode'.
Source Error:
Line 548: FacetResults resultFacets = null;
Line 549: if (facets != null && facets.Any()) {
Line 550: resultFacets = facets.Aggregate(query, (current, fname) => current.FacetOn(i => i[fname])).GetFacets();
Line 551: }
Line 552: // calling this before applying facetFilter should allow us to get a total facet set
From what I can understand about the error message it seems to not like that I am trying to compare two different fields to each other instead of comparing a field to a constant. The other odd thing is that the error seems to be pointing to a line of code that has to do with aggregating facets. I did a Google search and came up with absolutely nothing relating to this error. Any ideas?
Thanks,
Corey
I think what you are trying is not possible, and if you look at this that might indeed be the case. A solution that is given there is to put your logic in the index: create a ComputedField that checks your dates and puts a value in the index that you can search on (can be a simple boolean).
You will need to split your logic though - the query on the date range can still be done in the predicate (as it is relative to the current date) but the comparison of first and last should be done on index time instead of on query time.

Algorith that determinates frequency of string combinations MQL4

I have csv file like this:
1392249600;EUR;CHF;USD;JPY;GBP
1392163200;GBP;JPY;USD;CHF;EUR
1392076800;GBP;CHF;EUR;JPY;USD
1391990400;JPY;USD;EUR;CHF;GBP
1391904000;GBP;EUR;CHF;USD;JPY
1391731200;GBP;EUR;CHF;JPY;USD
1391644800;EUR;CHF;USD;JPY;GBP
1391558400;JPY;USD;EUR;CHF;GBP
There can be over 15 000 rows in that file. I am trying to write code that could do such thing:
1.Takes first row saves it as parent. Then takes next 3 days as that childs.
2.Counts how often and which combination off childs with that parent are inside this file.
3.It creates something like summary for that so I could read todays combination and script shows the only the most frequent child combinations for next 3 days.
I don't have mathematical thinking so I have big problems to find solution myself.
What I think first I need script that generates all posible combinations of these colums made of EUR,CHF,USD,JPY,GBP so there is posible 5*4*3*2*1 = 120 combinations. Because they cant repeat in single row.
It will be like this.
First parent will be combination from first row like this: EUR;CHF;USD;JPY;GBP
Then 3 childs would be
GBP;JPY;USD;CHF;EUR
GBP;CHF;EUR;JPY;USD
JPY;USD;EUR;CHF;GBP
It saves this combination off parent and child elements.
Then again it starts from begining of the file, but moves one row below(like iteration +1).
then next all childs would be
GBP;CHF;EUR;JPY;USD
JPY;USD;EUR;CHF;GBP
GBP;EUR;CHF;USD;JPY
And again it saves these combinations for counting and make some frequency results.
And this cycle repeats for all rows on csv file.
Is there maybe some tips I should consider how to create this type of programm ?
Any tip would be great !
Thank You Very Much!
BB
Can you please clarify whether first value in a row in your file is date/time? 1392249600;EUR;CHF;USD;JPY;GBP
If yes, are you expecting that there will total 4 rows with the same date/time?
Or else you just need to go sequentially and use Line-1 as parent and then Line-2, Line-3, Line-4 as child and goes on... so that Line-5 becomes parent again?
To check whether country code is equivalent or not, you can use below kind of code. I am not 100% sure about your requirement, please correct me if you think this is not what you are looking for and I will try to answer you in other way:
package com.collections;
public class CountryCodeComparison {
public static void main(String[] args) {
//Read every row and sequentially insert value in CountryCode object.
//For ex. your row is: 1392163200;GBP;JPY;USD;CHF;EUR
String s1 = "1392163200;GBP;JPY;USD;CHF;EUR";
String [] array1 = s1.split(";");
CountryCode cc1 = new CountryCode(array1[1], array1[2], array1[1], array1[4], array1[5]);
//For ex. your row is: 1392076800;GBP;CHF;EUR;JPY;USD
String s2 = "1392076800;GBP;CHF;EUR;JPY;USD";
String [] array2 = s2.split(";");
CountryCode cc2 = new CountryCode(array2[1], array2[2], array2[1], array2[4], array2[5]);
if(cc1.equals(cc2)) {
System.out.println("Both CountryCode objects are equal.");
} else {
System.out.println("Both CountryCode objects are NOT equal.");
}
}
}
class CountryCode {
private String countryCode1;
private String countryCode2;
private String countryCode3;
private String countryCode4;
private String countryCode5;
public CountryCode(String countryCode1, String countryCode2,
String countryCode3, String countryCode4, String countryCode5) {
this.countryCode1 = countryCode1;
this.countryCode2 = countryCode2;
this.countryCode3 = countryCode3;
this.countryCode4 = countryCode4;
this.countryCode5 = countryCode5;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((countryCode1 == null) ? 0 : countryCode1.hashCode());
result = prime * result
+ ((countryCode2 == null) ? 0 : countryCode2.hashCode());
result = prime * result
+ ((countryCode3 == null) ? 0 : countryCode3.hashCode());
result = prime * result
+ ((countryCode4 == null) ? 0 : countryCode4.hashCode());
result = prime * result
+ ((countryCode5 == null) ? 0 : countryCode5.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CountryCode other = (CountryCode) obj;
if (countryCode1 == null) {
if (other.countryCode1 != null)
return false;
} else if (!countryCode1.equals(other.countryCode1))
return false;
if (countryCode2 == null) {
if (other.countryCode2 != null)
return false;
} else if (!countryCode2.equals(other.countryCode2))
return false;
if (countryCode3 == null) {
if (other.countryCode3 != null)
return false;
} else if (!countryCode3.equals(other.countryCode3))
return false;
if (countryCode4 == null) {
if (other.countryCode4 != null)
return false;
} else if (!countryCode4.equals(other.countryCode4))
return false;
if (countryCode5 == null) {
if (other.countryCode5 != null)
return false;
} else if (!countryCode5.equals(other.countryCode5))
return false;
return true;
}
}

How to search on multiple strings entered in single text box in mvc3

i have a single textbox named Keywords.
User can enter multiple strings for search.
How this is possible in mvc3?
I am using nhibernate as ORM.
Can i create criteria for this?
Edited Scenario
I have partial view to search job based on following values:
Keywords(multiple strings), Industry(cascading dropdown with functional area )//working well ,FunctionalArea//working well
Loaction(multiple locations), Experience//working well
In Controller i am retrieving these values from form collection.
What datatype should i use for keywords and location (string or string[] )?
public ActionResult SearchResult(FormCollection formCollection)
{
IList<Jobs> JobsSearchResultList = new List<Jobs>();
//string[] keywords = null;
string location = null;
int? industry = 0;
int? functionaArea = 0;
int? experience = 0;
string keywords = null;
if (formCollection["txtKeyword"] != "")
{
keywords = formCollection["txtKeyword"];
}
//if (formCollection["txtKeyword"] != "")
//{
// keywordAry = formCollection["txtKeyword"].Split(' ');
// foreach (string keyword in keywordAry)
// {
// string value = keyword;
// }
//}
......retrieving other values from formcollection
....
//Now passing these values to Service method where i have criteria for job search
JobsSearchResultList = oEasyJobsService.GetJobsOnSearchExists(keywords,industry,functionaArea,location,experience);
return View(JobsSearchResultList);
}
In Services i have done like:
public IList<EASYJobs> GetJobsOnSearchExists(string keywords, int? industryId, int? functionalAreaId, string location, int? experience)
{
IList<JobLocation> locationlist = new List<JobLocation>();
IList<Jobs> JobsList = null;
var disjunction = Expression.Disjunction();
ICriteria query = session.CreateCriteria(typeof(Jobs), "EJobs");
if (keywords != null)
{
foreach (string keyword in keywords)
{
string pattern = String.Format("%{0}%", keyword);
disjunction
.Add(Restrictions.InsensitiveLike("Jobs.keywords", pattern,MatchMode.Anywhere))
.Add(Restrictions.InsensitiveLike("YJobs.PostTitle",pattern,MatchMode.Anywhere));
}
query.Add(disjunction)
.Add(Expression.Eq("EASYJobs.Industry.IndustryId", industryId))
.Add(Expression.Eq("Jobs.FunctionalArea.FunctionalAreaId", functionalAreaId))
.Add(Expression.Eq("Jobs.RequiredExperience", experience)));
}
else
{..
}
JobsList = criteria.List<Jobs>();
}
Problems i am facing are:
In controller if i use string[],then Split(',') does not split the string with specified separator.It passes string as it is to Service.
2.In services i am trying to replace string with %{0}% ,strings with spaces are replaced/concat() here with given delimeter.
But the problem here is It always return the whole job list means not giving the required output.
Pleas help ...
As long as you have a delimiter you can break the input into pieces on you should be able to create an or expression with the parts. You can use a disjunction to combine an arbitrary number of criteria using OR's.
var criteria = session.CreateCriteria<TestObject>();
Junction disjunction = Restrictions.Disjunction();
var input = "key words";
foreach (var keyword in input.Split(" "))
{
ICriterion criterion = Restrictions.Eq("PropertyName", keyword);
disjunction.Add(criterion);
}
criteria.Add(disjunction);
Multiple keywords with special characters or extra spaces are replaced with single space with Regex expressions.
And then keywords are separated with Split("").
Its working as required....
if (!string.IsNullOrEmpty(keywords))
{
keywords = keywords.Trim();
keywords = System.Text.RegularExpressions.Regex.Replace(keywords, #"[^0-9a-zA-Z\._\s]", " ");
keywords = System.Text.RegularExpressions.Regex.Replace(keywords, #"[\s]+", " ");
if (keywords.IndexOf(" ") > 0)
{
string[] arr = keywords.Split(" ".ToCharArray());
for (int i = 0; i < arr.Length; i++)
{
if (!string.IsNullOrEmpty(arr[i]))
{
criteria.Add(Restrictions.Disjunction()
.Add(Expression.Like("EASYJobs.keywords", arr[i], MatchMode.Anywhere)));
}
}
}
else
{
criteria.Add(Restrictions.Disjunction()
.Add(Expression.Like("EASYJobs.keywords", keywords, MatchMode.Anywhere)));
}
}

How to get out of repetitive if statements?

While looking though some code of the project I'm working on, I've come across a pretty hefty method which does
the following:
public string DataField(int id, string fieldName)
{
var data = _dataRepository.Find(id);
if (data != null)
{
if (data.A == null)
{
data.A = fieldName;
_dataRepository.InsertOrUpdate(data);
return "A";
}
if (data.B == null)
{
data.B = fieldName;
_dataRepository.InsertOrUpdate(data);
return "B";
}
// keep going data.C through data.Z doing the exact same code
}
}
Obviously having 26 if statements just to determine if a property is null and then to update that property and do a database call is
probably very naive in implementation. What would be a better way of doing this unit of work?
Thankfully C# is able to inspect and assign class members dynamically, so one option would be to create a map list and iterate over that.
public string DataField(int id, string fieldName)
{
var data = _dataRepository.Find(id);
List<string> props = new List<string>();
props.Add("A");
props.Add("B");
props.Add("C");
if (data != null)
{
Type t = typeof(data).GetType();
foreach (String entry in props) {
PropertyInfo pi = t.GetProperty(entry);
if (pi.GetValue(data) == null) {
pi.SetValue(data, fieldName);
_dataRepository.InsertOrUpdate(data);
return entry;
}
}
}
}
You could just loop through all the character from 'A' to 'Z'. It gets difficult because you want to access an attribute of your 'data' object with the corresponding name, but that should (as far as I know) be possible through the C# reflection functionality.
While you get rid of the consecutive if-statements this still won't make your code nice :P
there is a fancy linq solution for your problem using reflection:
but as it was said before: your datastructure is not very well thought through
public String DataField(int id, string fieldName)
{
var data = new { Z = "test", B="asd"};
Type p = data.GetType();
var value = (from System.Reflection.PropertyInfo fi
in p.GetProperties().OrderBy((fi) => fi.Name)
where fi.Name.Length == 1 && fi.GetValue(data, null) != null
select fi.Name).FirstOrDefault();
return value;
}
ta taaaaaaaaa
like that you get the property but the update is not yet done.
var data = _dataRepository.Find(id);
If possible, you should use another DataType without those 26 properties. That new DataType should have 1 property and the Find method should return an instance of that new DataType; then, you could get rid of the 26 if in a more natural way.
To return "A", "B" ... "Z", you could use this:
return (char)65; //In this example this si an "A"
And work with some transformation from data.Value to a number between 65 and 90 (A to Z).
Since you always set the lowest alphabet field first and return, you can use an additional field in your class that tracks the first available field. For example, this can be an integer lowest_alphabet_unset and you'd update it whenever you set data.{X}:
Init:
lowest_alphabet_unset = 0;
In DataField:
lowest_alphabet_unset ++;
switch (lowest_alphabet_unset) {
case 1:
/* A is free */
/* do something */
return 'A';
[...]
case 7:
/* A through F taken */
data.G = fieldName;
_dataRepository.InsertOrUpdate(data);
return 'G';
[...]
}
N.B. -- do not use, if data is object rather that structure.
what comes to my mind is that, if A-Z are all same type, then you could theoretically access memory directly to check for non null values.
start = &data;
for (i = 0; i < 26; i++){
if ((typeof_elem) *(start + sizeof(elem)*i) != null){
*(start + sizeof(elem)*i) = fieldName;
return (char) (65 + i);
}
}
not tested but to give an idea ;)

Resources