Insert & Delete values in many to many relation table - asp.net

I want to insert values to many to many relation table
I'm using entity framework & linq. and I want to build up the Insert query (.net Framework 4)
following are the tables
Menus -
menu_id,
menu_name,
menu_desc
Cater - cater_id,
cater_name,
enable_ind
Relation table
Menu_Cater - menu_id,
cater_id
I have tried with couple of cases seems not working,
if there is a SIMPLE way of implementing this insert & delete

Assuming you have the Menu and Cater objects (from the dropdown list or however), simply:
create a Menu_Cater record
set it to insert on submit
submit changes
Demonstrated below:
VB.NET
Dim menu As Menu = GetSelectedMenu() ' However you get the Menu record
Dim cater As Cater = GetSelectedCater() ' However you get the Cater record
Dim relationship = New Menu_Cater()
' EITHER:
relationship.menu_id = menu.menu_id
relationship.cater_id = cater.cater_id
' OR:
' relationship.menu = menu
' relationship.cater = cater
Using db = new MyDataContext
db.Menu_Cater.InsertOnSubmit( relationship )
db.SubmitChanges()
End Using
C#
Menu menu = GetSelectedMenu(); // However you get the Menu record
Cater cater = GetSelectedCater(); // However you get the Cater record
Menu_Cater relationship = new Menu_Cater();
// EITHER:
relationship.menu_id = menu.menu_id;
relationship.cater_id = cater.cater_id;
// OR:
// relationship.menu = menu
// relationship.cater = cater
using (db = new MyDataContext()) {
db.Menu_Cater.InsertOnSubmit(relationship);
db.SubmitChanges();
}
Small changes may need to be made for your variable/database-field names. And maybe db.Save() instead of db.SubmitChanges() depending on the type of data context.

I don't know, if You need it now, but Ill show how to do it.
If I have understood right, You mean smth like that.
public ActionResult Create(Cater cater, int menuId)
{
//Find menu with our menu_id
Menu menu = db.Menus.Where(m => m.menu_id == menuId).FirstOrDefault();
//Add cater for this Menu
menu.Cater.Add(cater);
db.SaveChanges();
return somethere...
}
public ActionResult Remove(int caterId, int menuId)
{
//Choose menu, from him we will delete cater which we need
Menu menu = db.Menus.Where(m => m.menu_id == menuId).FirstOrDefault();
//Find cater which we want delete from this Menu
Cater cater = menu.Cater.Where(c => c.cater_id == caterId).FirstOrDefault();
//Remove him from Table Menu_Cater
menu.Cater.Remove(cater);
db.SaveChanges();
return somethere...
}
Thats all. Its work for MVC4

Related

Trying To Filter Only Rows That Meet Two Criteria

I promise I have read through the Query information page, but obviously I am missing/misunderstanding something.
I have a Table that has the statuses for multiple departments (the fields are Strings). When a user loads that table I want App Maker to hide jobs that have been finished.
The way we categorize a job as finishes is when:
The Inventory Status = Complete and when the The Delivery Status = Delivered.
Both these conditions need to be met.
Example:
Inventory (Complete) + Delivery (Delivered) = hide
Inventory (In Progress) + Delivery (Delivered) = don't hide
Inventory (Complete) + Delivery (Scheduled) = don't hide
I tried the following, however it hides all the example listed above, not just the first one.
var datasource = app.datasources.SystemOrders;
var inventory = ['Complete'];
var delivery = ['Delivered'];
datasource.query.filters.InventoryStatus._notIn = inventory;
datasource.query.filters.DeliveryStatus._notIn = delivery;
datasource.load();
I have also tried this:
var datasource = app.datasources.SystemOrders;
datasource.query.filters.InventoryStatus._notIn = 'Complete';
datasource.query.filters.DeliveryStatus._notIn = 'Delivered';
datasource.load();
But I get this error:
Type mismatch: Cannot set type String for property _notIn. Type List is expected. at SystemOrders.ToolBar.Button2.onClick:2:46
Any help would be greatly appreciated.
Filters are using AND operator. Please consider switching the Datasource Query Builder and applying the following query:
"InventoryStatus != :CompleteStatus OR DeliveryStatus != :DeliveredStatus"
Set CompleteStatus variable to Complete
Set DeliveredStatus variable to Delivered
Explanation:
Filter you want to apply is "NOT(InventoryStatus = Complete AND DeliveryStatus = Delivered)" which is equivalent to "InventoryStatus != Complete OR DeliveryStatus != Delivered".
Vasyl answer my question perfectly, but I wanted to add a few details in case anyone needs to do the same thing and aren't familiar with using the Datasource Query Builder.
All I did was click the Database I was using and then clicked the Datasources section at the top.
I clicked Add Datasource, named it a new name and pasted Vasyl's code into the Query Builder Expression box.
Two new boxes appear below it allowing me to enter the desired statuses that I wanted to filter out.
Lastly I went back to my Table and changed its datasource to my newly created datasource.
Since you are changing your datasource, if you have any extra code on there it may need to be updated to point to the new datasource.
Example:
I had some buttons that would filter entries for the various departments.
So this:
widget.datasource.query.clearFilters();
var datasource = app.datasources.SystemOrders;
var statuses = ['Complete'];
datasource.query.filters.WarehouseStatus._notIn = statuses;
datasource.load();
had to change to this:
widget.datasource.query.clearFilters();
var datasource = app.datasources.SystemOrders_HideComplete;
var statuses = ['Complete'];
datasource.query.filters.WarehouseStatus._notIn = statuses;
datasource.load();
You can use multiple run and then concatenate their results something like following
/**
* Retrieves records for ActionItems datasource.
* #param {RecordQuery} query - query object of the datasource;
* #return {Array<ActionItems>} user's rating as an array.
*/
function getActionItemsForUser_(query) {
var userRoles = app.getActiveUserRoles();
query.filters.Owner._contains = Session.getActiveUser().getEmail();
var ownerRecords = query.run();
query.clearFilters();
query.filters.AddedBy._contains = Session.getActiveUser().getEmail();
var addedByRecords = query.run();
return addedByRecords.concat(ownerRecords);
}

Removing item from list in EF model

I'm using Entity Framework and I am trying to remove a NinjqEquiment from a list belonging to an instance of Ninja.When I retrieve the list of Ninjas,I make sure to include the equipment list, so I know they are there. Then I remove the equipment from the Ninja and try to save changes. I get the following error -
The entity type List`1 is not part of the model for the current
context.
using (var db = new NinjaDbContext())
{
//get ninjas with equipment included
var ninjas = GetAllNinjas();
//get ninja
var ninja = (from n in ninjas
where n.Id == id
select n).FirstOrDefault();
//get equipment
var eq = (from e in ninja.EquipmentOwned
where e.Id == removeEqId
select e).FirstOrDefault();
//remove eq from ninja
ninja.EquipmentOwned.Remove(eq);
//Make sure entity knows EquipmentOwned has been modified
db.Entry(ninja.EquipmentOwned).State = EntityState.Modified;
//save ninja
db.SaveChanges();
}
Just remove this:
//Make sure entity knows EquipmentOwned has been modified
db.Entry(ninja.EquipmentOwned).State = EntityState.Modified;
This causes the error.
EquipmentOwned is a List<Equipment>. It is not an Entry in EF terms so it is not tracked directly by it.
When you delete an entity from such collection, EF knows that there won't be any relationship between this particular ninja and this particular equipment. It won't delete equipment from database because other ninjas may use this equipment.
To delete it completely you should remove this equipment from corresponding DbSet<> like this:
using (var db = new NinjaContext())
{
//db.Equipment is a DbSet<Equipment>
//id is PrimaryKey of Equipment table
var eq = db.Equipment.Find(id);
db.Equipment.Remove(eq);
db.SaveChanges();
}

Need help in listing all data retrieve from Microsoft SQL Server

I'm new to asp .net web application.
Is it possible to retrieve data from Microsoft SQL Server and preview it in a menu drop down list where the data are already flter by alphabetical? For example when I click the menu "A", it will drop down menu and show the option I have for the menu "A".
Any one that done it before and can provide me the link to make it happen? If possible, the design is responsive design .
Thanks
I have a categories like This you can save them in database
enum MenuCategory { Cata = 1, Catb = 2 };
Add a menu control:
var menu1 = new Menu() { ID = "TestMenu" };
now we add first level of menu that is our category:
var cat = MenuCategory.Cata;
var menuItem = new MenuItem(cat.ToString(), cat.ToString());
menu1.Items.Add(menuItem);
now adding sublevel for this category. Get data from database by your method
var catItems = new DAL.Repositories.MenuRepository().GetAMenutblByCategory(Convert.ToInt16(cat));
now for each data that you retrieve from database add a menuitem:
foreach (var menutbl in catItems)
{
var childmenuItem = new MenuItem(menutbl.MenuValue, menutbl.MenuId.ToString(), "", menutbl.NavigationUrl);
menu1.FindItem(cat.ToString()).ChildItems.Add(childmenuItem);
}
You should do this for all of your category, And finally add your menu to page.
Panel1.Controls.Add(menu1);
if you are doing this on pageload please be sure checkin !ispostback
new MenuItem(strin text,string value, string imageurl,string navigationurl)

Saving changes of Entity Framework in Asp.Net

I have created an entity Appraiser and there are methods to select values, display data etc.
Now I want to save the changes made after data is displayed, I have a button named SAVE, which will be used to save changes.
I am not able to get how to save the changes of this Entity?
Entity name is Appraiser, and I have created methods like get AppriaserDetails etc in DAL, BL and used them in aspx.cs.
This is my code:
public void UpdateData(Appraiser appId)
{
var Appsave = context.Appraisers.FirstOrDefault(App => App.AppraiserId == appId.AppraiserId);
Appsave.AppraiserName = appId.AppraiserName;
Appsave.AppraiserPhones = appId.AppraiserPhones;
Appsave.AppraiserAppraiserCompanyId = appId.AppraiserAppraiserCompanyId;
Appsave.Address = appId.Address;
Appsave.City = appId.City;
Appsave.ProvinceState = appId.ProvinceState;
Appsave.Email = appId.Email;
context.SaveChanges();
}
If u want to insert new record, then can use
MyContext.Appraisers.AddObject(appraiserEntityObject);
MyContext.SaveChanges();
In case of update
if (appraiserEntityObject.EntityState == EntityState.Detached)
{
// In case of web, we got an existing record back from the browser. That object is not attached to the context yet.
MyContext.Appraisers.Attach(appraiserEntityObject);
MyContext.ObjectStateManager.ChangeObjectState(appraiserEntityObject, EntityState.Modified);
}
MyContext.SaveChanges();
Here MyContext is ur ObjectContext

Return unordered list from hierarchical sql data

I have table with pageId, parentPageId, title columns.
Is there a way to return unordered nested list using asp.net, cte, stored procedure, UDF... anything?
Table looks like this:
PageID ParentId Title
1 null Home
2 null Products
3 null Services
4 2 Category 1
5 2 Category 2
6 5 Subcategory 1
7 5 SubCategory 2
8 6 Third Level Category 1
...
Result should look like this:
Home
Products
Category 1
SubCategory 1
Third Level Category 1
SubCategory 2
Category 2
Services
Ideally, list should contain <a> tags as well, but I hope I can add it myself if I find a way to create <ul> list.
EDIT 1: I thought that already there is a solution for this, but it seems that there isn't. I wanted to keep it simple as possible and to escape using ASP.NET menu at any cost, because it uses tables by default. Then I have to use CSS Adapters etc.
Even if I decide to go down the "ASP.NET menu" route I was able to find only this approach: http://aspalliance.com/822 which uses DataAdapter and DataSet :(
Any more modern or efficient way?
Using linq2sql you could do:
List<PageInfo> GetHierarchicalPages()
{
var pages = myContext.PageInfos.ToList();
var parentPages = pages.Where(p=>p.ParentId == null).ToList();
foreach(var page in parentPages)
{
BuildTree(
page,
p=> p.Pages = pages.Where(child=>p.pageId == child.ParentId).ToList()
);
}
}
void BuildTree<T>(T parent, Func<T,List<T>> setAndGetChildrenFunc)
{
foreach(var child in setAndGetChildrenFunc(parent))
{
BuildTree(child, setAndGetChildrenFunc);
}
}
Assuming you define a Pages property in the PageInfo like:
public partial class PageInfo{
public List<PageInfo> Pages{get;set;}
}
The processing to get it on a hierarchy is happening on web application side, which avoids extra load on the sql server. Also note that this type of info is a perfect candidate to cache.
You can do the render as Rex mentioned. Alternatively you could expand a bit on this implementation and make it support the hierarchy interfaces and use asp.net controls.
Update 1: For the rendering variation you asked on a comment, you can:
var sb = new System.IO.StringWriter();
var writer = new HtmlTextWriter(sb);
// rex's rendering code
var html = sb.ToString();
Best practice would be to do this using IHierarchyData and IHierarchalEnumerable and DataBind to a custom control which inherits from HierarchalDataBoundControl (this is the base for controls like TreeView).
However, let's try for a quick-and-dirty, not-especially-efficient, simple example in c#:
//class to hold our object graph in memory
//this is only a good idea if you have a small number of items
//(less than a few thousand)
//if so, this is a very flexible and reusable way to represent your tree
public class Page
{
public string Title {get;set;}
public int ID {get;set;}
public Collection<Page> Pages = new Collection<Page>();
public Page FindPage(int id)
{
return FindPage(this, id);
}
private Page FindPage(Page page, int id)
{
if(page.ID == id)
{
return page;
}
Page returnPage = null;
foreach(Page child in page.Pages)
{
returnPage = child.FindPage(id);
if(returnPage != null)
{
break;
}
}
return returnPage;
}
}
//construct our object graph
DataTable data = SelectAllDataFromTable_OrderedByParentIDAscending();
List<Page> topPages = new List<Page>();
foreach(DataRow row in data.Rows)
{
Page page = new Page();
page.Title = (string)row["Title"];
page.ID = (int)row["PageID"];
if(row["ParentID"] == null)
{
topPages.Add(page);
}
else
{
int parentID = (int)row["ParentID"];
foreach(Page topPage in topPages)
{
Page parentPage = topPage.FindPage(parentID);
if(parentPage != null)
{
parentPage.Pages.Add(page);
break;
}
}
}
}
//render to page
public override void Render(HtmlTextWriter writer)
{
writer.WriteFullBeginTag("ul");
foreach(Page child in topPages)
{
RenderPage(writer, child);
}
writer.WriteEndTag("ul");
}
private void RenderPage(HtmlTextWriter writer, Page page)
{
writer.WriteFullBeginTag("li");
writer.WriteBeginTag("a");
writer.WriteAttribute("href", "url");
writer.Write(HtmlTextWriter.TagRightChar);
writer.Write(page.Title);
writer.WriteEndTag("a");
if(page.Pages.Count > 0)
{
writer.WriteFullBeginTag("ul");
foreach(Page child in page.Pages)
{
RenderPage(writer, child);
}
writer.WriteEndTag("ul");
}
writer.WriteEndTag("li");
}
This should get you started.
with x (pageID, title)
as (
select cast(title as varchar(100)),pageID
from pages
where parentID is null
union all
select cast(x.title||' - '||e.title as varchar(100)),
e.pageID
from pages e, x
where e.parentID = x.pageID
)
select title as title_tree
from x
order by 1
Output:
TITLE_TREE
Home
Products
Services
Products - Category 1
Products - Category 2
Products - Category 2 - Subcategory 1
Products - Category 2 - Subcategory 1 - Third Level Category 1
Products - Category 2 - Subcategory 2
Have you considered getting XML output from SQL Server using SELECT ... FOR XML EXPLICIT? Your data seems set up perfectly for that.
For an example:
http://www.eggheadcafe.com/articles/20030804.asp
If you want to pursue I could work through an example.
RexM - firstly I must state that I'm a front-end developer so can't even touch you for skill and knowedge of coding C#. However - I did implement your solution using the Page object and encountered a problem. Yes, sorry I'm a "pleaseSendMeTheCode" leech in this instance, but neverless, thought it was important to detail the "bug".
I'm building a site that uses a nested UL to display menu items and allows the user to re-sort the menu however they want.
My menu has the following data fields: pageID, parentID, pageOrder, pageTitle
Page order refers to the order in which the pages appear in a node.
So my query for SelectAllDataFromTable_OrderedByParentIDAscending();was:
SELECT * FROM [pages] ORDER BY [parentID] ASC, [pageOrder] ASC
I then use jsTree to make the menu items draggable and droppable.
I re-ordered a few pages and discovered a bug:
Say my structure is like so:
home
cars
usa
muscle cars
suvs
europe
colours
directions
vertical
horizontal
up
down
If I move "cars" (and all it's children) inside "down", the children of "cars" no longer display in the menu. That's the "bug".
I have checked the db and parentID and pageOrder are all correct under "cars", I also tried changing my SQL query, starting from scratch, all sorts of testing directly on the DB (all the above with jsTree turned off so I can see the basic nested UL) - but with no success.
Just wondering, as I've seen other forums pointing to this page for solutions to turning hierarchical sql data into nested UL's, it might be worth somebody looking into it.
As my whole site is based on the use of Javascript I've now implemented a Jquery.ajax solution (which, very badly commented, is on my site here) to build the nested UL but as I said, just flagging as potential problem.
Thanks very much though for a kick start in my own finding of a solution!

Resources