One of the requirements of a module I am currently building requires me to select data using Linq but the ids are being passed to me thru an integer array
var CheckedArray = Request["doc_download"];
string[] detailIds = CheckedArray.Split(',');
List<int> dtIds = new List<int>();
foreach (string words in detailIds)
{
dtIds.Add(Int32.Parse(words));
}
using (var ctx = new Connect2020Entities())
{
DetailList = (from userDetail in ctx.DocumentDetail
where userDetail.ID == <!-- items in dtIds --> //<<I do not know what could be used to compare all of the data from the array in a single query>>
select new DetailList()
{
FilePath = userDetail.FilePath
}).ToList<UserDocument>();
}
What could be done so that all of the ids inside the integer array can be compared inside the query in one go. I currently could not think of a viable logic that will allow the values in the array to be used as parameters in the query I am using.
*The DocumentDetail field ID is an integer.
you can try is use Contains()
ctx.DocumentDetail.Where(ele => dtIds.Contains(ele.ID)).ToList();
or in your current syntax
where dtIds.Contains(userDetail.ID)
Related
I'm trying to understand the purpose of the BasedOnSchemas option in the OrganizationalItemItemsFilterData filter.
The documentation clearly states:
"Gets or sets the BasedOnSchemas condition to return only items that are using the given schemas"
So it should be possible to only retrieve components of a specific schema, right?
here's my code:
LinkToSchemaData[] schemaLinks = new[] {
new LinkToSchemaData { IdRef = "tcm:113-362325-8" }
};
OrganizationalItemItemsFilterData filter =
new OrganizationalItemItemsFilterData();
filter.BaseColumns = ListBaseColumns.Extended;
filter.ItemTypes = new ItemType[] { ItemType.Component };
filter.Recursive = true;
filter.BasedOnSchemas = schemaLinks;
XElement items = client.GetListXml("tcm:113-14192-2", filter);
The XElement items will however, contain multiple types of components, not only those of schema tcm:113-362325-8
How can I retrieve only those components that are based on my schema?
Using both BasedOnSchemas and Recursive = true is not supported. Remove the the recursiveness and you'll find that the schema filter works.
If you want to get a "recursive" list of all Components for a certain Schema, consider doing a WhereUsed on the Schema.
GetListXml("tcm:5-59-8", new UsingItemsFilterData())
Morning,
I would like to know how to write the following SQL statement in LINQ.
SELECT TOP 6 * FROM Questions
ORDER BY NEWID()
I would also like to know, how i could bind this to a asp.net repeater control to display the 6 questions.
Many thanks :)
The Linq style would be
Questions.OrderBy(q=>Guid.NewGuid()).Take(6)
then you attach that to a repeater by setting its DataSource property to the above, and calling the DataBind method.
You would have to be able to invoke the NEWID() function to generate your random guids. To do so, you could take some hints here and first create a pseudo-method mapped to the NEWID() function on your data context.
[System.Data.Linq.Mapping.Function(Name="NEWID", IsComposable=true)]
public Guid NewId()
{
throw new NotImplementedException();
}
Once that is set, you could then write your query to use this function:
var query = dc.Questions
.OrderBy(question => dc.NewId())
.Take(6);
You can inspect the SQL query generated for this and it should match.
Questions.OrderBy(q=>Sql.NewGuid()).Take(6)
This will invoke the NEWID() in SQL statement.
(from db in context.Questions
order by Guid.NewGuid()
select db).Take(6);
I know answer is already selected, but still I'm adding my way to achieve this. Faced same situation today and tried couple of ways, used questions.OrderBy(q => Guid.NewGuid()).ToList() and couple of more suggestions. Later I thought to add a new field string RandomOrder in view model and assigned Guid.NewGuid().ToString() in loop and then used questions.OrderBy(i => i.RandomOrder).ToList() and this worked great.
I had requirement to shuffle questions if author selected option shuffleAlways while creating assessment. If not then sort on regular sorting order. Here is complete solution:
private List<AssessmentQuestionsViewModel> LoadAllQuestions(string assessmentId, bool shuffleQuestions)
{
List<AssessmentQuestionsViewModel> questions = new List<AssessmentQuestionsViewModel>();
var items = assessmentQuestionRepository.GetAll().Where(i => i.AssessmentId == assessmentId).ToList();
foreach (var item in items)
{
questions.Add(new AssessmentQuestionsViewModel
{
Id = item.Id,
AssessmentId = item.AssessmentId,
QuestionText = item.QuestionText,
HintText = item.HintText,
QuestionType = item.QuestionType,
MaxMarks = item.MaxMarks,
SortOrder = item.SortOrder,
RandomOrder = Guid.NewGuid().ToString(),
Answers = LoadAllAnswers(item.Id)
});
}
if (shuffleQuestions)
{
questions = questions.OrderBy(i => i.RandomOrder).ToList();
}
else
{
questions = questions.OrderBy(i => i.SortOrder).ToList();
}
return questions;
}
And this worked like charm. Hope this help others.
I assume you are using ORDER BY NEWID() as a way to select random data from your questions? If so, you should avoid using NEWID() (or it's LINQ equivalent), causes tons a new guid to be generated for every record in your table. On a large dataset, that's devestating.
Instead, see Linq Orderby random ThreadSafe for use in ASP.NET for an optimized solution to random sorts. Then just add a take operator and your set.
Random random = new Random();
int seed = random.Next();
var RandomQuestions = Questions.OrderBy( s => (~(s.Shuffle & seed)) & (s.Shuffle | seed)); // ^ seed);
return RandomQuestions.Take(6);
I have the following function in by Data Access Layer but I am receiving the following error on my RETURN statement.
The type arguments for method
'System.Data.DataTableExtensions.CopyToDataTable(System.Collections.Generic.IEnumerable)'
cannot be inferred from the usage. Try
specifying the type arguments
explicitly
My code is:
DL.FVRGDataContext db = new FVRGDataContext();
public DataTable getRestaurants(string cuisineName)
{
var cuisineIdFind = from CUISINE in db.CUISINEs
where CUISINE.CUISINE_NAME == cuisineName
select CUISINE.CUISINE_ID;
var restaurantList = from RESTAURANT in db.RESTAURANTs
where RESTAURANT.CUISINE_ID == 2
orderby RESTAURANT.REST_NAME ascending
select i;
DataTable result = new DataTable();
result = restaurantList.CopyToDataTable();
return result;
}
CopyToDataTable doesn't work this way... it has a generic parameter T, where T must be a subclass of DataRow. In other words CopyToDataTable can't be used to convert an arbitrary collection to DataTable, the items of the collection must be DataRows themselves.
In your case, CUISINE and RESTAURANT seem to be Linq to SQL or Entity Framework entities, not DataRows, so it can't work.
I'm trying to use LINQ to SQL to select a few specific columns from a table and return the result as a strongly typed list of objects.
For Example:
var result = (from a in DataContext.Persons
where a.Age > 18
select new Person
{
Name = a.Name,
Age = a.Age
}
).ToList();
Any help would be greatly appreciated.
It builds fine, but when I run it, I get the error. Explicit construction of entity type MyEntity in query is not allowed.
Basically you are doing it the right way. However, you should use an instance of the DataContext for querying (it's not obvious that DataContext is an instance or the type name from your query):
var result = (from a in new DataContext().Persons
where a.Age > 18
select new Person { Name = a.Name, Age = a.Age }).ToList();
Apparently, the Person class is your LINQ to SQL generated entity class. You should create your own class if you only want some of the columns:
class PersonInformation {
public string Name {get;set;}
public int Age {get;set;}
}
var result = (from a in new DataContext().Persons
where a.Age > 18
select new PersonInformation { Name = a.Name, Age = a.Age }).ToList();
You can freely swap var with List<PersonInformation> here without affecting anything (as this is what the compiler does).
Otherwise, if you are working locally with the query, I suggest considering an anonymous type:
var result = (from a in new DataContext().Persons
where a.Age > 18
select new { a.Name, a.Age }).ToList();
Note that in all of these cases, the result is statically typed (it's type is known at compile time). The latter type is a List of a compiler generated anonymous class similar to the PersonInformation class I wrote above. As of C# 3.0, there's no dynamic typing in the language.
UPDATE:
If you really want to return a List<Person> (which might or might not be the best thing to do), you can do this:
var result = from a in new DataContext().Persons
where a.Age > 18
select new { a.Name, a.Age };
List<Person> list = result.AsEnumerable()
.Select(o => new Person {
Name = o.Name,
Age = o.Age
}).ToList();
You can merge the above statements too, but I separated them for clarity.
The issue was in fact that one of the properties was a relation to another table. I changed my LINQ query so that it could get the same data from a different method without needing to load the entire table.
Thank you all for your help!
Make a call to the DB searching with myid (Id of the row) and get back specific columns:
var columns = db.Notifications
.Where(x => x.Id == myid)
.Select(n => new { n.NotificationTitle,
n.NotificationDescription,
n.NotificationOrder });
Currently in my ASP.Net applications web.config I have an application setting that stores a comma delimited list of mapping values, like the one below. In the code behind I need to perform a lookup on this data based on input values 1, 2, 3 etc. I can either string split it and loop until I find a match, or use Regex to pull the value from the config string.
Currently i'm using Regex to get the mapping value. I'm not opposed to changing how the data is stored in the web.config. Is there a more simple and elegant way of handling this?
<add key="Mappings" value="1|APP,2|TRG,3|KPK,4|KWT,5|CUT" />
If you need to use this lookup frequently and the string in web.config doesn't change very often, then it makes sense to parse the string once into a Dictionary object and store that in the Application or Cache.
Lookups from the Dictionary will be lightning fast, especially compared to parsing the string each time.
private static readonly object _MappingsLock = new object();
public static string GetMapping(int id)
{
// lock to avoid race conditions
lock (_MappingsLock)
{
// try to get the dictionary from the application object
Dictionary<int, string> mappingsDictionary =
(Dictionary<int, string>)Application["MappingsDictionary"];
if (mappingsDictionary == null)
{
// the dictionary wasn't found in the application object
// so we'll create it from the string in web.config
mappingsDictionary = new Dictionary<int, string>();
foreach (string s in mappingsStringFromWebConfig.Split(','))
{
string[] a = s.Split('|');
mappingsDictionary.Add(int.Parse(a[0]), a[1]);
}
// store the dictionary in the application object
// next time around we won't need to recreate it
Application["MappingsDictionary"] = mappingsDictionary;
}
// now do the lookup in the dictionary
return mappingsDictionary[id];
}
}
// eg, get the mapping for id 4
string mapping = GetMapping(4); // returns "KWT"
Just curious :) What about LINQ
string inputValue = "2";
string fromConfig = "1|APP,2|TRG,3|KPK,4|KWT,5|CUT";
string result = fromConfig
.Split(',')
.Where(s => s.StartsWith(inputValue))
.Select(s => s.Split('|')[1])
.FirstOrDefault();
Or
Regex parseRegex = new Regex(#"((?<Key>\d)\|(?<Value>\S{3}),?)");
parseRegex.Matches(fromConfig)
.Cast<Match>()
.Where(m => m.Groups["Key"].Value == inputValue)
.Select(m => m.Groups["Value"].Value)
.FirstOrDefault();
Split the string on commas, then each substring on |, store these in a Dictionary and find it by key.
That's just as an alternative to Regex. You know what they say about Regex.