How do I save multiple selections from List to EF Model? - model-view-controller

I am trying to learn how to submit multiple selections from a list to the model created between two data models. I have tried the following:
var tag = context.TagInformation.Find(model.Tags[0]);
var newlyCreatedUser = context.Users.Find(user.Id);
newlyCreatedUser.TagInfo = new List<TagInformation>(0) { tag };
context.SaveChanges();
I have also tried the following:
var tags = new List<TagInformation>();
foreach (var tag in model.Tags)
{
var tag= context.TagInformation.Find(model.Tags[0]);
if (tag != null)
{
tags.Add(tag);
}
}
var newlyCreatedUser = context.Users.Find(user.Id);
newlyCreatedUser.TagInfo = tags;
context.SaveChanges();
I have searched on Google and tried to find what value I need to change here in order to save all selected values from model.Tags, but currently only the first selected value is saved. To my understanding, the [0] is causing it to only save the first selected tag. I need to automatically save any combination of selected tags from the List, regardless of how many tags are in the list.
I can see that all of the select tags are loaded during debugging, and the foreach statement gets passed through for each selected id, but still only saves the first tag selected in the list.
What must I change to obtain this result and where can I find documentation to help me understand? Thanks in advance.

var tag= context.TagInformation.Find(model.Tags[0]);
this line of code always select the first tag, you should do something like
var tag= context.TagInformation.Find(tag);

Related

Xamarin Shell Flyout created from database data

I have app of lists and items in each list. The list and their items are stored in two tables. A list data would be like "Grocery" and the list items like "bananas" etc. You can add lists and items in the app. Right now I have a list content page that lists the list names. Tap one and you go to a content page of the items in that list. This works, but I want to populate the Shell flyout with the list names from a database query in the AppShell.xaml.cs file. I want to do something like this:
ShellSection shell_section = new ShellSection();
var lists = await SLOMBListDataStore.GetSLOMBListsAsync(true);
foreach (var list in lists)
{
shell_section.Title = list.ListName;
shell_section.Icon = "tab_feed.png";
shell_section.Items.Add(new ShellContent() { Content = new SLOMBListDataPage(new SLOMBListDataViewModel(list.id)) });
this.Items.Add(shell_section);
}
BindingContext = this;
This, by the way, does not work. Creating the entries works manually if I use shell_section1, shell_section2 etc, but then you have to hard code the lists. Is it possible to do what I want, create the flyout from the query data? Thanks
Try to put the initialization code into the for loop like:
var lists = await SLOMBListDataStore.GetSLOMBListsAsync(true);
foreach (var list in lists)
{
ShellSection shell_section = new ShellSection();
shell_section.Title = list.ListName;
shell_section.Icon = "tab_feed.png";
shell_section.Items.Add(new ShellContent() { Content = new SLOMBListDataPage(new SLOMBListDataViewModel(list.id)) });
this.Items.Add(shell_section);
}
You need a new instance for each record.

how to update observable collection group

I have implemented group observable collection like below.
Grouped Property
private ObservableCollection<Grouping<String, Request>> _groupedList = null;
public ObservableCollection<Grouping<String, Request>> GroupedList {
get {
return _groupedList;
}
set {
_groupedList = value;
RaisePropertyChanged(() => GroupedList);
}
}
Creating List
var list = new List<Request>();
var grouped = from Model in list
group Model by Model.Done into Group
select new Grouping<string, Request>(Group.Key, Group);
GroupedList = new ObservableCollection<Grouping<string, TModel>>(grouped);
Now i need to update one item in the list without reloading full list for performance.
i did tried like this , mylist.FirstOrDefault(i => i.Id== mymodel.Id); Not worked for me.
I need to pick that particular item and edit and update into the list again using linq or something but i stuck here for group observable collection no efficient details to do this., anybody having idea about this help please.
And finally i get updated single item, but i need to do that without
GroupedList = new ObservableCollection<Grouping<string, TModel>>(grouped);
Because everytime it create new list and bind into my view.Thats again big performance though.
Thanks in advance.
What I understand from your question is that you want to push an updated group without overwriting the entire ObservableCollection.
To do that:
var targetGroup = GroupedList.FirstOrDefault(i => i.Id == mymodel.Id);
var targetIndex = GroupedList.IndexOf(targetGroup);
var modifiedGroup = ... //Do whatever you want to do
GroupedList[targetIndex] = modifiedGroup;
This will trigger a 'replace' operation of the target grouping.

unable to get multiple entries in SelectEntries of DotNetZip

I'm trying to use DotNetZipLib-DevKit-v1.9 in my MVC3 Project to extract the files to a specific folder.
What i want is -- How to add multiple entries in zip.SelectEntries method.
Here is my code in controller action:
public ActionResult ExtractZip(string fileName, HttpPostedFileBase fileData)
{
string zipToUnpack = #"C:\Users\Public\Pictures\Sample Pictures\images.zip";
string unpackDirectory = System.IO.Path.GetTempPath();
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
// here, we extract every entry, but we could extract conditionally
// based on entry name, size, date, checkbox status, etc.
var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;");//This shows `0` items in collections
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
return Json(true);
}
In this line var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;"); if i specify only single extension ,it works fine
ex:
var collections = zip1.SelectEntries("name=*.gif"); this works good
I've also seen SelectEntries method here, but it doesn't help though
How to add multiple entries ?
Finally i could answer my own question.
Inorder to select multiple entries we need to use OR and to select multiple entries use the following code:
var collections = zip1.SelectEntries("(name=*.jpg) OR (name=*.jpeg) OR (name=*.png) OR (name=*.gif)");
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}

Using an list in a query in entity framework

I am trying to find a way to pass in an optional string list to a query. What I am trying to do is filter a list of tags by the relationship between them. For example if c# was selected my program would suggest only tags that appear in documents with a c# tag and then on the selection of the next, say SQL, the tags that are linked to docs for those two tags together would be shown, whittling it down so that the user can get closer and closer to his goal.
At the moment all I have is:
List<Tag> _tags = (from t in Tags
where t.allocateTagDoc.Count > 0
select t).ToList();
This is in a method that would be called repeatedly with the optional args as tags were selected.
I think I have been coming at it arse-backwards. If I make two(or more) queries one for each supplied tag, find the docs where they all appear together and then bring out all the tags that go with them... Or would that be too many hits on the db? Can I do it entirely through an entity context variable and just query the model?
Thanks again for any help!
You can try this.
First collect tag to search in a list of strings .
List<string> tagStrings = new List<string>{"c#", "sql"};
pass this list in your query, check whether it is empty or not, if empty, it will return all the tags, else tags which matches the tagStrings.
var _tags = (from t in Tags
where t.allocateTagDoc.Count > 0
&& (tagStrings.Count ==0 || tagStrings.Contains(t.tagName))
select t).ToList();
You can also try this, Dictionary represents ID of a document with it's tags:
Dictionary<int, string[]> documents =
new Dictionary<int, string[]>();
documents.Add(1, new string[] { "C#", "SQL", "EF" });
documents.Add(2, new string[] { "C#", "Interop" });
documents.Add(3, new string[] { "Javascript", "ASP.NET" });
documents.Add(4, new string[] { });
// returns tags belonging to documents with IDs 1, 2
string[] filterTags = new string[] { "C#" };
var relatedTags = GetRelatedTags(documents, filterTags);
Debug.WriteLine(string.Join(",", relatedTags));
// returns tags belonging to document with ID 1
filterTags = new string[] { "C#", "SQL" };
relatedTags = GetRelatedTags(documents, filterTags);
Debug.WriteLine(string.Join(",", relatedTags));
// returns tags belonging to all documents
// since no filtering tags are specified
filterTags = new string[] { };
relatedTags = GetRelatedTags(documents, filterTags);
Debug.WriteLine(string.Join(",", relatedTags));
public static string[] GetRelatedTags(
Dictionary<int, string[]> documents,
string[] filterTags)
{
var documentsWithFilterTags = documents.Where(o =>
filterTags
.Intersect(o.Value).Count() == filterTags.Length);
string[] relatedTags = new string[0];
foreach (string[] tags in documentsWithFilterTags.Select(o => o.Value))
relatedTags = relatedTags
.Concat(tags)
.Distinct()
.ToArray();
return relatedTags;
}
Thought I would pop back and share my solution which was completely different to what I first had in mind.
First I altered the database a little getting rid of a useless field in the allocateDocumentTag table which enabled me to use the entity framework model much more efficiently by allowing me to leave that table out and access it purely through the relationship between Tag and Document.
When I fill my form the first time I just display all the tags that have a relationship with a document. Using my search filter after that, when a Tag is selected in a checkedListBox the Document id's that are associated with that Tag(s) are returned and are then fed back to fill the used tag listbox.
public static List<Tag> fillUsed(List<int> docIds = null)
{
List<Tag> used = new List<Tag>();
if (docIds == null || docIds.Count() < 1)
{
used = (from t in frmFocus._context.Tags
where t.Documents.Count >= 1
select t).ToList();
}
else
{
used = (from t in frmFocus._context.Tags
where t.Documents.Any(d => docIds.Contains(d.id))
select t).ToList();
}
return used;
}
From there the tags feed into the doc search and vice versa. Hope this can help someone else, if the answer is unclear or you need more code then just leave a comment and I'll try and sort it.

How to Update one Sharepoint List (calendar) from Another (custom)?

As part of an EvenReceiver the itemAdded on a custom List (source) creates a Calendar entry in another List (target).
I now want to add an itemUpdated event so that when the the source List is updated the change is filtered through to the target List.
I am using c# in Visual Studio to develop the Event Receiver.
Can anyone please advise the best way to do this and how I create the link between the two Lists to ensure I can update from source to target?
Thank you.
You will have to udpate the target list yourself...
var sourceItem = this.properties.ListItem;
//you can use other properties to search for the item in the targetlist aswell
string query = string.Format("<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>{0}</Value></Eq></Where>", sourceItem.Title);
var spQuery = new SPQuery() { Query = query };
var foundItems = targetList.GetItems(spQuery);
if(foundItems.Count == 1)
{
var foundItem = foundItems[0];
//update the properties you want
foundItem["Property1"] = sourceItem["Property1"];
foundItem["Property2"] = sourceItem["Property2"];
foundItem["Property3"] = sourceItem["Property3"];
foundItem.Update();
}
Note that this piece of code is straight out of my head & untested ;-)

Resources