I need to query a list in SharePoint where the columns may be added in the future.
For instance at the moment I have the following columns
Name, Job, interests, address
I want to be able to query this string dynamically using a parameter from the browser so if columns are added in the future I don’t have to change the code but just the parameter.
The address may look like this www.contoso.com/sites/mypage.aspx?property=Interests
And the code something on the line of this:
var SiteParameter = Request.QueryString["property"];
var ItemsFromList = from item in ListItems where item[try to put the parameter in here] select item;
I use SPmetal to get the list details, so if I press item. Visual Studio2010 will return the columns within the list.
This may be easier without SPMetal.
var qy = new SPQuery();
qy.Query =
"<Where><Eq>" +
"<FieldRef Name=`" + siteParameter + "'/>" +
// You may have to worry about the type of the field here, too.
"<Value Type='Text'>" + desiredValue + "</Value>" +
"</Eq></Where>";
var itemCollection = myList.GetItems(qy);
Related
Suppose I have database table named Items that have a Column called Name. Inside Items I have a chair, which name is 'Black wooden chair'.
Because there will be millions of Items, I have created a Full-Text index on Name, to be able to search efficiently. I want a search so that every word of search phrase is contained in the Name. For example:
Searching for 'chair wooden' should return an item with 'Black wooden chair' Name, but 'chair wooden whatever' should not return it. Therefore I use a function called 'Contains' that supports Full-Text search:
var userInput = "chair wooden";
var searchQuery = userInput.Split().Aggregate((s1, s2) => "\"" + s1 + "\"" + " AND " + "\"" + s2 + "\"");
// searchQuery = "chair" AND "wooden"
var result = dbCtx.Items.FirstOrDefault(i => EF.Functions.Contains(i.Name, searchQuery));
This just however calls for an SQL injection if user types input such as 'test" AND test'.
Is there any other way that EF Core could handle such query building for me?
I'm using LINQ for querying the database. I'm using dynamic keyword in queries. I don't know this dynamic mechanism in depth, so I don't understand what's going on.
The situation follows. The following section of code:
var qGroup = qLocalOrd.GroupBy("new(...)", "it");
var qGroupCast = (qGroup as IQueryable<IGrouping<dynamic,dynamic>>).AsEnumerable();
var qAgg = from ordg in qGroupCast
select new {
ordg.Key,
Agg = (ordg.Key.OsID + " " + ordg.Key.NameOs + "\n" +
(ordg as IEnumerable<dynamic>).Aggregate("Составные части:\n", ...).Trim('\n') + ...)
};
Works just fine. But when I'm adding this to the end:
var qPlain = qAgg.Cast<dynamic>().AsQueryable().Select("new(Key.SubSchet, Key.NameSubSchet, ...)");
qPlain.Dump();
I'm receiving an error like "No field "Key" exists in type "Object"". It's the same if I use
(qAgg as IEnumerable<dynamic>)
So at this point dynamic treatment of qAgg elements is broken somewhy.
Why does this happen and how to make this thing work?
I have a need to search a data source using LINQ.
In essence, the query that I want would be something like:
select * from table where id in ("1","2","4");
The added "complexity" is that the values inside the parenthesis will be coming out of string list.
This is my code:
public void getAdUserData(List<String> _inADUserDatas)
{
var records = from _adUserDatas in _adUserDataDBDataContex.ADUserDatas
where
new string[] { (char)34 + String.Join((char)34 + "," + (char)34, _inADUserDatas) + (char)34 }.Contains(_adUserDatas.fan)
orderby _adUserDatas.fan
select _adUserDatas;
var test = records.ToList();
Console.WriteLine((char)34 + String.Join((char)34 + "," + (char)34, _inADUserDatas) + (char)34);
as can be seen, I use String.join to convert my list into a comma-delimited string where every string is enclosed by a double-quote.
I've also tried using the code below without any luck.
new string[] {String.Join(",", _inADUserDatas) }.Contains(_adUserDatas.fan)
I also tried manually typing some of the ID in the list into the query and I am getting records.
I believe I am doing it right but it's not returning any records. The variable test has a count of 0.
Any ideas what could be wrong? I've gotten the ideas to my code by combining several discussions here in stackoverflow particularly this link here and this other link.
Thanks a lot
Call Contains on the list itself. Query provider should handle it out of the box:
var records = from _adUserDatas in _adUserDataDBDataContex.ADUserDatas
where _inADUserDatas.Contains(_adUserDatas.fan)
orderby _adUserDatas.fan
select _adUserDatas;
Just use contains on your collection:
var records = from _adUserDatas in _adUserDataDBDataContex.ADUserDatas
where _inADUserDatas.Contains(_adUserDatas.fan)
orderby _adUserDatas.fan
select _adUserDatas;
you can use below mentioned code
var list=_adUserDataDBDataContex.ADUserDatas.Where(p=>p.Contains(_adUserDatas.fan));
What's the data type for ids?
a simple collection.Where(s=> ids.Contains(s)) will translate to "in"
I'm not sure how linq to SQL translates these sorts of queries, but you don't need to sting join with commas in EF, try it without manually trying to create a comma separated list.
I have working code (thank you John Socha-Leialoha) that uses the TFS API to retrieve work items, along with all their linked work items (code below). However, what I'm trying to do is access the names of the linked Files (TFS calls it a "Versioned Item") for each work item. In the TFS GUI you can link a file to a work item. Say Work Item 1234 is linked to file foo.txt. Now when I run this query to find linked items, that file is not in the list - only other children WIs or parent WIs are returned. It's the same result if I create and run the query entirely in the GUI. How can I find out which files are linked to a given WI? The only way I can now is to look at the WI in the TFS GUI, and it shows in the Files list in the lower right.
Perhaps I just need to do a normal flat query, fetch the WI fields, and somehow the names of the linked files would be one of the fields of that WI? I don't need to download the linked file, I just need the filename/location.
Code to return all linked WIs is here:
public List<string> GetLinkedItems()
{
//executes a linked item query, returning work items, as well as the items that are link to them.
//gets digital asset work item that contains the given part number in the Assoc. Parts field
var result = new List<string>();
var tpc = new TfsTeamProjectCollection(new Uri(_tfsUri));
var workItemStore = (WorkItemStore) tpc.GetService(typeof (WorkItemStore));
//and [Schilling.TFS.TechPub.AssocParts] CONTAINS '101-4108'
var query =
"SELECT [System.Id], [System.Links.LinkType], [System.TeamProject]," +
" [System.WorkItemType], [System.Title], [System.AssignedTo]," +
" [System.State] FROM WorkItemLinks " +
" WHERE ([Source].[System.TeamProject] = 'Tech Pubs' AND " +
" [Source].[System.WorkItemType] = 'DigitalAsset' AND " +
" [Source].[System.State] <> '') And " +
" ([System.Links.LinkType] <> '') And " +
" ([Target].[System.WorkItemType] <> '') " +
" ORDER BY [System.Id] mode(MayContain)";
var treeQuery = new Query(workItemStore, query);
//Note we need to call RunLinkQuery here, not RunQuery, because we are doing a link item type of query
var links = treeQuery.RunLinkQuery();
//// Build the list of work items for which we want to retrieve more information//
int[] ids = (from WorkItemLinkInfo info in links
select info.TargetId).Distinct().ToArray();
//
// Next we want to create a new query that will retrieve all the column values from the original query, for
// each of the work item IDs returned by the original query.
//
var detailsWiql = new StringBuilder();
detailsWiql.AppendLine("SELECT");
bool first = true;
foreach (FieldDefinition field in treeQuery.DisplayFieldList)
{
detailsWiql.Append(" ");
if (!first)
detailsWiql.Append(",");
detailsWiql.AppendLine("[" + field.ReferenceName + "]");
first = false;
}
detailsWiql.AppendLine("FROM WorkItems");
//
// Get the work item details
//
var flatQuery = new Query(workItemStore, detailsWiql.ToString(), ids);
WorkItemCollection details = flatQuery.RunQuery();
return
(from WorkItem wi in details
select wi.Id + ", " + wi.Project.Name + ", " + wi.Title + ", " + wi.State).ToList();
}
Work item queries can only show WorkItemLinkType links. To get links of other types (i.e. files in source control), you need to go through the list of links in the WorkItem object itself. Here's a snippet of code that will get you the artifact of the file linked to the work item:
TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("http://<server>:8080/tfs/<collection>"));
WorkItemStore wiStore = tpc.GetService<WorkItemStore>();
VersionControlServer vc = tpc.GetService<VersionControlServer>();
WorkItem task = wiStore.GetWorkItem(<work item with a linked file>);
var externalLinks = task.Links.OfType<ExternalLink>();
foreach (var link in externalLinks)
{
XmlDocument artifact = vc.ArtifactProvider.GetArtifactDocument(new Uri(link.LinkedArtifactUri));
}
The XML document contains all necessary information needed to grab the correct file version from the VersionControlServer using the GetItem() method.
form.myDataTable.Rows[i][2 * cs] = corr;
form.myDataTable.Rows[i][2 * cs + 1] = "p" + Convert.ToString(col1)
+ " p" + Convert.ToString(col2);
I need to sort 2*cs column by values and also corresponding names in column 2*cs+1.
I am trying like this:
var corrvalues = new Dictionary();
correlationvalues["p" + Convert.ToString(col1)
+ " p" + Convert.ToString(col2)] = corr;
sortedvalues = correlationvalues.Values.OrderByDescending;
I am not clear how to use orderbydescending, i am new to c#. Thanks for help.
OrderByDescending is a function, not a property. It has one required parameter, which is a function that takes a value in the collection (in your case, correctionvalues.Values) and returns a "key" to use for comparison purposes. If you just want to compare directly on the values themselves, you can pass in an identity lambda function (e.g. x => x).
var corrvalues = new Dictionary();
correlationvalues["p" + Convert.ToString(col1)
+ " p" + Convert.ToString(col2)] = corr;
sortedvalues = correlationvalues.Values.OrderByDescending(val => val);
If your values are more complex types (such as a Person class) and you want to sort on a particular field (such as Name), then you could pass in something like this:
sorted = personDict.Values.OrderByDescending(person => person.Name);
See http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderbydescending.aspx for more detail on OrderByDescending.
You can also learn more about lambda expressions (which is useful if you're new to C#) here: http://msdn.microsoft.com/en-us/library/bb397687.aspx