LinQ to SQL missing data - c#

I'm trying to get all rows from my SANPHAM table but somehow it keeps missing some rows. The table has 9 rows, however, when displayed, it show only 5 rows (I have picture below, and don't mind about products' image, I will add the rests later).
I have tried to do something in my code, I change int i = 0 to int i = 1 and there are 2 situations. With i = 0, the result misses even rows and with i = 1, odd rows disappear.
I am a newbie to this, I looked for some solutions but still can't fix it, hope you guys can help
Here is my code:
HomeControllers.cs:
namespace MvcApplication.Controllers
{
public class HomeController : Controller
{
private LinQtoSQLDataContext LinQtoSQLDataContext = new LinQtoSQLDataContext();
public ActionResult Index()
{
IList<Models.SanPhamModels> sanPhamList = new List<Models.SanPhamModels>();
var query = from sanpham in LinQtoSQLDataContext.SANPHAMs select sanpham;
var sps = query.ToList();
foreach (var sanPhamData in sps)
{
sanPhamList.Add(new Models.SanPhamModels()
{
maSanPham = sanPhamData.maSanPham,
tenSanPham = sanPhamData.tenSanPham,
gia = sanPhamData.gia,
tacGia = sanPhamData.tacGia,
moTa = sanPhamData.moTa,
maDanhMuc = sanPhamData.maDanhMuc,
hinhAnh = sanPhamData.hinhAnh
});
}
return View(sanPhamList);
}
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}
Index.cshtml:
#for (int i=0; i<Model.Count; i++)
{
var tmp = "<div class=\"product_box\">";
tmp += "<img src=\""+ Url.Content(Model[i].hinhAnh) + "\" alt=\"Image\" /><br>";
tmp += Html.ActionLink(Model[i].tenSanPham, "productdetail", new { maSanPham = Model[i].maSanPham }, null);
tmp += "<p class=\'product_price\">" + Model[i].gia.ToString() + "</p>";
tmp += Html.ActionLink("Add to Cart", "shoppingcart", new { maSanPham = Model[i].maSanPham }, new {#class = "add_to_card"});
tmp += Html.ActionLink("Detail", "productdetail", new { maSanPham = Model[i].maSanPham }, new { #class = "detail" });
tmp += "</div>";
#Html.Raw(tmp)
}
SanPhamModels:
namespace MvcApplication.Models
{
public class SanPhamModels
{
public string maSanPham { get; set; }
public string tenSanPham { get; set; }
public double gia { get; set; }
public string tacGia { get; set; }
public string moTa { get; set; }
public string maDanhMuc { get; set; }
public string hinhAnh { get; set; }
}
}
My database
My website result image
EDITED:
I see what problem with my project:
Problem
a <div> inside a <div> so that it shows only the odd rows or even rows. Now I am working on this issue, still need some help...

you have to define the model in top with list as you are returning the list from controller.
#model IEnumerable<Models.SanPhamModels>

Related

adding multiple values in object list in web api c#

I am new to web api and C#. I am creating a function where I am calling values from table which has 33 rows. the query is this:
Select * from T_SVRS_Reg_Trans
I have created a model where I have put out properties like so:
public class UserModel
{
public int ID { get; set; }
public string OrgUnit { get; set; }
public string TDC { get; set; }
public string CustCode { get; set; }
public string CustName { get; set; }
public string DestCode { get; set; }
public string EMV { get; set; }
public string Service { get; set; }
public string SPCCode { get; set; }
public string SPCode { get; set; }
public string Remarks { get; set; }
public int Stage { get; set; }
public string Cost { get; set; }
public string SAPUpdate { get; set; }
public string Active { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public string UpdatedBy { get; set; }
public DateTime UpdatedOn { get; set; }
}
Now I am calling the table values to get added in these properties. My function for that is this:
[HttpPost]
[Route("GetTableValue")]
public IHttpActionResult GetTableValue()
{
try
{
UserModel objUserModel = new UserModel();
ManageUserData ObjManageUserData = new ManageUserData();
var sqlDataTable = ObjManageUserData.GetTableValue();
if (sqlDataTable.Rows.Count > 0)
{
for (int i = 0; (i < sqlDataTable.Rows.Count); i++)
{
objUserModel.OrgUnit=(sqlDataTable.Rows[i]["TRT_Org_ID"].ToString());
objUserModel.TDC = (sqlDataTable.Rows[i]["TRT_TDC_Code"].ToString());
objUserModel.CustCode = (sqlDataTable.Rows[i]["TRT_Cust_Code"].ToString());
objUserModel.CustName = (sqlDataTable.Rows[i]["TRT_Cust_Name"].ToString());
objUserModel.DestCode = (sqlDataTable.Rows[i]["TRT_Dest_Code"].ToString());
objUserModel.EMV = (sqlDataTable.Rows[i]["TRT_EMV"].ToString());
objUserModel.Service = (sqlDataTable.Rows[i]["TRT_Service"].ToString());
objUserModel.SPCCode = (sqlDataTable.Rows[i]["TRT_SPC_Code"].ToString());
objUserModel.SPCode = (sqlDataTable.Rows[i]["TRT_SP_Code"].ToString());
objUserModel.Remarks = (sqlDataTable.Rows[i]["TRT_Remarks"].ToString());
objUserModel.Stage = (int)(sqlDataTable.Rows[i]["TRT_Stage"]);
objUserModel.Cost = (sqlDataTable.Rows[i]["TRT_Cost_Imp"].ToString());
objUserModel.SAPUpdate = (sqlDataTable.Rows[i]["TRT_SAP_Update_Status"].ToString());
objUserModel.Active = (sqlDataTable.Rows[i]["TRT_IS_ACTIVE"].ToString());
objUserModel.CreatedBy = (sqlDataTable.Rows[i]["TRT_CREATED_BY"].ToString());
objUserModel.CreatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_CREATED_ON"]);
objUserModel.UpdatedBy = (sqlDataTable.Rows[i]["TRT_UPDATED_BY"].ToString());
objUserModel.UpdatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_UPDATED_ON"]);
}
}
return Ok(objUserModel);
}
catch (Exception ex)
{
return Content(HttpStatusCode.NoContent, "Something went wrong");
}
However I am noticing that only the last table value is added to the model and the rest of it is not. I want to add all 33 values in model form to the model mentioned. Is there any way to do this?
PLease help
}
You overwrite objUserModel each iteration. Create a new one inside the loop, add them to a List<UserModel>, returning that to your view.
Also consider dropping the archaic Hungarian notation (the "obj" prefix). Also consider using an ORM instead of mapping columns to properties using strings.
You should create a List or Array of type UserModel and adding items into it
try
{
List<UserModel> result = new List<UserModel>();
ManageUserData ObjManageUserData = new ManageUserData();
var sqlDataTable = ObjManageUserData.GetTableValue();
if (sqlDataTable.Rows.Count > 0)
{
for (int i = 0; (i < sqlDataTable.Rows.Count); i++)
{
UserModel objUserModel = new UserModel();
objUserModel.OrgUnit = (sqlDataTable.Rows[i]["TRT_Org_ID"].ToString());
objUserModel.TDC = (sqlDataTable.Rows[i]["TRT_TDC_Code"].ToString());
objUserModel.CustCode = (sqlDataTable.Rows[i]["TRT_Cust_Code"].ToString());
objUserModel.CustName = (sqlDataTable.Rows[i]["TRT_Cust_Name"].ToString());
objUserModel.DestCode = (sqlDataTable.Rows[i]["TRT_Dest_Code"].ToString());
objUserModel.EMV = (sqlDataTable.Rows[i]["TRT_EMV"].ToString());
objUserModel.Service = (sqlDataTable.Rows[i]["TRT_Service"].ToString());
objUserModel.SPCCode = (sqlDataTable.Rows[i]["TRT_SPC_Code"].ToString());
objUserModel.SPCode = (sqlDataTable.Rows[i]["TRT_SP_Code"].ToString());
objUserModel.Remarks = (sqlDataTable.Rows[i]["TRT_Remarks"].ToString());
objUserModel.Stage = (int)(sqlDataTable.Rows[i]["TRT_Stage"]);
objUserModel.Cost = (sqlDataTable.Rows[i]["TRT_Cost_Imp"].ToString());
objUserModel.SAPUpdate = (sqlDataTable.Rows[i]["TRT_SAP_Update_Status"].ToString());
objUserModel.Active = (sqlDataTable.Rows[i]["TRT_IS_ACTIVE"].ToString());
objUserModel.CreatedBy = (sqlDataTable.Rows[i]["TRT_CREATED_BY"].ToString());
objUserModel.CreatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_CREATED_ON"]);
objUserModel.UpdatedBy = (sqlDataTable.Rows[i]["TRT_UPDATED_BY"].ToString());
objUserModel.UpdatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_UPDATED_ON"]);
result.Add(objUserModel);
}
}
return Ok(result);
}
catch (Exception ex)
{
return Content(HttpStatusCode.NoContent, "Something went wrong");
}
You need to use the collection instead of single object UserModel.
[HttpPost]
[Route("GetTableValue")]
public IHttpActionResult GetTableValue()
{
try
{
ManageUserData ObjManageUserData = new ManageUserData();
var sqlDataTable = ObjManageUserData.GetTableValue();
List<UserModel> userModels = new List<UserModel>();
if (sqlDataTable.Rows.Count > 0)
{
for (int i = 0; (i < sqlDataTable.Rows.Count); i++)
{
var objUserModel = new UserModel()
objUserModel.OrgUnit = (sqlDataTable.Rows[i]["TRT_Org_ID"].ToString());
objUserModel.TDC = (sqlDataTable.Rows[i]["TRT_TDC_Code"].ToString());
objUserModel.CustCode = (sqlDataTable.Rows[i]["TRT_Cust_Code"].ToString());
objUserModel.CustName = (sqlDataTable.Rows[i]["TRT_Cust_Name"].ToString());
objUserModel.DestCode = (sqlDataTable.Rows[i]["TRT_Dest_Code"].ToString());
objUserModel.EMV = (sqlDataTable.Rows[i]["TRT_EMV"].ToString());
objUserModel.Service = (sqlDataTable.Rows[i]["TRT_Service"].ToString());
objUserModel.SPCCode = (sqlDataTable.Rows[i]["TRT_SPC_Code"].ToString());
objUserModel.SPCode = (sqlDataTable.Rows[i]["TRT_SP_Code"].ToString());
objUserModel.Remarks = (sqlDataTable.Rows[i]["TRT_Remarks"].ToString());
objUserModel.Stage = (int)(sqlDataTable.Rows[i]["TRT_Stage"]);
objUserModel.Cost = (sqlDataTable.Rows[i]["TRT_Cost_Imp"].ToString());
objUserModel.SAPUpdate = (sqlDataTable.Rows[i]["TRT_SAP_Update_Status"].ToString());
objUserModel.Active = (sqlDataTable.Rows[i]["TRT_IS_ACTIVE"].ToString());
objUserModel.CreatedBy = (sqlDataTable.Rows[i]["TRT_CREATED_BY"].ToString());
objUserModel.CreatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_CREATED_ON"]);
objUserModel.UpdatedBy = (sqlDataTable.Rows[i]["TRT_UPDATED_BY"].ToString());
objUserModel.UpdatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_UPDATED_ON"]);
userModels.Add(userModels);
}
}
return Ok(userModels);
}
catch (Exception ex)
{
return Content(HttpStatusCode.NoContent, "Something went wrong");
}
}
As you are expecting more than one row to be returned, you need to collect the rows as you iterate your result set into some sort of collection/list/array.
Try making a list of your UserModel
List<UserModel> objUserModels = new List<UserModel>();
And then adding each object to the list after each iteration of your for loop:
for (int i = 0; (i < sqlDataTable.Rows.Count); i++)
{
var objUserModel = new UserModel();
objUserModel.OrgUnit=(sqlDataTable.Rows[i]["TRT_Org_ID"].ToString());
objUserModel.TDC = (sqlDataTable.Rows[i]["TRT_TDC_Code"].ToString());
objUserModel.CustCode = (sqlDataTable.Rows[i]["TRT_Cust_Code"].ToString());
objUserModel.CustName = (sqlDataTable.Rows[i]["TRT_Cust_Name"].ToString());
objUserModel.DestCode = (sqlDataTable.Rows[i]["TRT_Dest_Code"].ToString());
objUserModel.EMV = (sqlDataTable.Rows[i]["TRT_EMV"].ToString());
objUserModel.Service = (sqlDataTable.Rows[i]["TRT_Service"].ToString());
objUserModel.SPCCode = (sqlDataTable.Rows[i]["TRT_SPC_Code"].ToString());
objUserModel.SPCode = (sqlDataTable.Rows[i]["TRT_SP_Code"].ToString());
objUserModel.Remarks = (sqlDataTable.Rows[i]["TRT_Remarks"].ToString());
objUserModel.Stage = (int)(sqlDataTable.Rows[i]["TRT_Stage"]);
objUserModel.Cost = (sqlDataTable.Rows[i]["TRT_Cost_Imp"].ToString());
objUserModel.SAPUpdate = (sqlDataTable.Rows[i]["TRT_SAP_Update_Status"].ToString());
objUserModel.Active = (sqlDataTable.Rows[i]["TRT_IS_ACTIVE"].ToString());
objUserModel.CreatedBy = (sqlDataTable.Rows[i]["TRT_CREATED_BY"].ToString());
objUserModel.CreatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_CREATED_ON"]);
objUserModel.UpdatedBy = (sqlDataTable.Rows[i]["TRT_UPDATED_BY"].ToString());
objUserModel.UpdatedOn = (DateTime)(sqlDataTable.Rows[i]["TRT_UPDATED_ON"]);
objUserModels.Add(objUserModel);
}
And then return your list of objects:
return Ok(objUserModels);

Passing Data from View to Controller using ViewModel

I want to pass Data of a Form from view to Controller with ViewModel is that possible?? I am getting null while sending data. My Code is :
My ViewModel contain model class reference. The data which i want to pass is for two model i.e MasterSchoolInfo and MasterUserInfo, but on submitting the posted value in controller is showing bull. Any help on this will be very helpful. I am new to Asp.Net MVC.
If i am passing Models to the contoller, then that is working fine, but once i changed it to viewmodel it started posting null to controller.
I idea behind changing from Model to ViewModel was because i want to pass data for two different Models and use them in the controller.
ViewModel
namespace ABC.ViewModels
{
public class UserInfoViewModel
{
public MasterSchoolInfo School { get; set; }
public MasterTeacherInfo Teacher{ get; set; }
public MasterStudentInfo Student { get; set; }
public MasterParentInfo Parent { get; set; }
public MasterUserInfo User { get; set; }
public MasterUserRole Role { get; set; }
}
}
Controller
[HttpPost]
public ContentResult CreateSchool(UserInfoViewModel _usrData)
{
var content = string.Empty;
if ((!String.IsNullOrEmpty(HttpContext.Session.GetString("UserEmail"))) && (!String.IsNullOrEmpty(HttpContext.Session.GetString("UserRole"))))
{
int UserId = Convert.ToInt32(HttpContext.Session.GetString("UserId"));
string UserEmail = Convert.ToString(HttpContext.Session.GetString("UserEmail"));
string UserRole = Convert.ToString(HttpContext.Session.GetString("UserRole"));
byte[] salt = encryption.generatePasswordSalt("school");
string password = encryption.generateHashedPassword("school", salt);
if (UserRole == "Super Administrator")
{
_usrData.School.CreatedBy = UserEmail;
_usrData.School.CreatedOn = DateTime.Now;
_usrData.School.ApprovalStatus = true;
_usrData.School.Status = true;
MasterUserInfo userInfo = new MasterUserInfo();
userInfo.RoleId = 4;
userInfo.EmailId = _usrData.School.PrimaryEmailId;
userInfo.Salt = Convert.ToBase64String(salt).ToString();
userInfo.Password = password;
userInfo.CreatedBy = UserEmail;
userInfo.CreatedOn = DateTime.Now;
userInfo.ApprovalStatus = true;
userInfo.Status = true;
//string[] str = schoolInfo.PrimaryEmailId.Split('.');
//userInfo.Username = str[0].ToString();
userInfo.Username = _usrData.User.Username.ToString();
MasterSchoolInfo masterSchool = _context.Set<MasterSchoolInfo>().LastOrDefault();
if (masterSchool != null)
{
var lastschoolcode = masterSchool.OpinschoolCode;
var val = lastschoolcode.Substring(4, lastschoolcode.Length - 4);
int r = Convert.ToInt32(val) + 1;
string newusercode = "IESC000" + r;
userInfo.UserCode = newusercode;
_usrData.School.OpinschoolCode = newusercode;
}
else
{
string newusercode = "IESC000" + 1;
userInfo.UserCode = newusercode;
_usrData.School.OpinschoolCode = newusercode;
}
if (ModelState.IsValid)
{
_context.MasterUserInfo.Add(userInfo);
_context.SaveChanges();
MasterUserInfo masterUser = _context.Set<MasterUserInfo>().Last();
_usrData.School.UserId = masterUser.Id;
_context.MasterSchoolInfo.Add(_usrData.School);
_context.SaveChanges();
TempData["Message"] = "School Added Successfully!";
content = "Success";
}
else
{
content = "Error";
}
}
else
{
content = "Error";
}
}
else
{
content = "Error";
}
return Content(content);
}
for example if your Code is :
public class MasterSchoolInfo
{
public string name{get;set;}
}
you should implement input in view:
<input type="text" name="school.name">

load one item per page [ Pagination ]

I have a viewpage like below
this is the controller method for above view
public ActionResult Add_Product()
{
var model = new AddNewProduct
{
ListProductFields = db.AB_ProductTypeCategoryField.ToList()
};
return View(model);
}
this is model class for above view
public class AddNewProduct
{
public string Product_ID { get; set; }
public string ProductTypeID { get; set; }
public string ProductCategoryID { get; set; }
public string Subsidary_ID { get; set; }
public IList<AB_ProductTypeCategoryField> ListProductFields { get; set; }
}
public partial class AB_ProductTypeCategoryField
{
public string Field_Value_EN { get; set; }
public string Field_Value_AR { get; set; }
}
this is viewpage
#model albaraka.Models.AddNewProduct
#using (Html.BeginForm())
{
#for (int i = 0; i < Model.ListProductFields.Count; i++)
{
#Html.TextAreaFor(m => m.ListProductFields[i].Field_Value_EN, new { #class = "form-control summernote", #row = 5 })
#Html.TextAreaFor(m => m.ListProductFields[i].Field_Value_AR, new { #class = "form-control summernote", #row = 5 })
}
}
Now I want to add pagination for above view page and limit one ListProductFields per one page , for that I following this Tutorial
So I change my code to like this
public ActionResult Add_Product(int? page)
{
var dummyItems = db.AB_ProductTypeCategoryField.Select(x => "Item " + x);
var pager = new PaginationModel.Pager(dummyItems.Count(), page);
var model = new AddNewProduct
{
Items = dummyItems.Skip((pager.CurrentPage - 1) * pager.PageSize).Take(pager.PageSize).ToList(),
Pager = pager
};
return View(model);
}
But then I'm getting following Run-time Error
Values of type 'AB_ProductTypeCategoryField' can not be converted to string.
Just try with following code , so you cannot use Skip method alone. so have use OrderBy before it
var dummyItems = db.AB_ProductTypeCategoryField;
var pager = new PaginationModel.Pager(dummyItems.Count(), page);
var model = new AddNewProduct
{
ListProductFields = dummyItems.OrderBy(i => i.SomeProperty).Skip((pager.CurrentPage - 1) * pager.PageSize).Take(pager.PageSize).ToList(),
Pager = pager
};
return View(model);
The issue of your observation is below line
var dummyItems = db.AB_ProductTypeCategoryField.Select(x => "Item " + x);
Since you are trying to select object with string concatenate operation ("Item " + x) that's why exception is thrown as AB_ProductTypeCategoryField is an object. I don't think you require "Item " + x at all.
You can change AddNewProdcut action implementation as
public ActionResult Add_Product(int? page)
{
var pager = new PaginationModel.Pager(dummyItems.Count(), page);
var model = new AddNewProduct
{
ListProductFields = db.AB_ProductTypeCategoryField.Skip((pager.CurrentPage - 1) * pager.PageSize).Take(pager.PageSize).ToList(),
Pager = pager
};
return View(model);
}

How to set up a "Details" page when parsing from XML file in ASP.NET MVC

I have an MVC VS2013 project querying an XML document.
The index action on my controller returns a list of Restaurants, and I need to be able to click the individual restaurants and open a details page which will show the respective properties of that Restaurant.
In previous projects querying from a sql database I would just call the db context, for example
Restaurant restaurant = db.Restaurants.Find(id);
but I am uncertain what the XML querying equivalent is.
Here is what I have so far.
Model:
[XmlRoot("EstablishmentCollection")]
public class Restaurant
{
[Key]
[XmlElement("FHRSID")]
public int? FHRSID { get; set; }
[XmlElement("BusinessName")]
public string BusinessName { get; set; }
[XmlElement("RatingValue")]
public int? RatingValue { get; set; }
[XmlElement("Hygiene")]
public int? HygieneScore { get; set; }
}
Controller:
public ActionResult Index()
{
IQueryable<Restaurant> Res = null;
try
{
var qy = xmlDoc.Descendants("EstablishmentDetail").Select(n => new Restaurant()
{
FHRSID = (int)n.Element("FHRSID"),
BusinessName = n.Element("BusinessName").Value,
RatingValue = RValue(n),
HygieneScore = HScores(n)
});
Res = qy.AsQueryable();
}
catch (Exception ex)
{
string message;
message = ex.Message.ToString();
return View(message);
}
return View(Res);
}
public ActionResult Details (int? id)
{
try
{
var qy = xmlDoc.Descendants("EstablishmentDetail").Select(n => new Restaurant()
{
FHRSID = (int)n.Element("FHRSID"),
BusinessName = n.Element("BusinessName").Value,
RatingValue = RValue(n),
HygieneScore = HScores(n)
});
//What goes here???
}
catch (Exception ex)
{
string message;
message = ex.Message.ToString();
return View(message);
}
return View();
}
Details View:
#model WebApplication3.Models.Restaurant
<h2>Details</h2>
<h6>#Model.FHRSID</h6>
<h6>#Model.BusinessName</h6>
<h6>#Model.HygieneScore</h6>
<h6>#Model.RatingValue</h6>
EDIT:
I have been working on it, is something like the below heading in the right direction?
(Controller)
public ActionResult Details (int? id)
{
var qy = xmlDoc.Descendants("EstablishmentDetail").Select(n => new Restaurant()
{
FHRSID = (int)n.Element("FHRSID"),
BusinessName = n.Element("BusinessName").Value,
RatingValue = RValue(n),
HygieneScore = HScores(n)
}).ToList();
var query = from x in qy
where x.FHRSID == id
select new Restaurant();
return View(query);
}
Problem with the above is that I am having issues correctly sending the query to the view
var r = xmlDoc.Descendants("EstablishmentDetail")
.Select(n => new Restaurant()
{
FHRSID = (int)n.Element("FHRSID"),
BusinessName = n.Element("BusinessName").Value,
RatingValue = RValue(n),
HygieneScore = HScores(n)
})
.Single(r => r.FHRSID == id);
Single, SignleOrDefault, First, FirstOrDefault returns an element from a collection.

A concise way to handle multiple checkboxes for a model

I have two classes, Songs and Tags.The relationship is many-to-many. The problem I'm having is that when a user adds a new Song and checks off what Tags s/he wants and I call db.SaveChanges() in the controller, it adds duplicate Tags instead of adding only records to the join table. I've worked around this, but it's a hack. There's got to be a better solution?
Here's my code (abrreviated for clarity).
Song:
public int Id { get; set; }
public List<Tag> Tags { get; set; }
public string SongTitle { get; set; }
Tag:
public int Id { get; set; }
public string TagName { get; set; }
public bool Selected { get; set; }
public List<Song> Songs { get; set; }
Controller:
public ActionResult Create()
{
Song song = new Song();
song.Tags = utilities.TagNames(_db, User.Identity.Name);
return View(song);
}
[HttpPost]
public ActionResult Create(Song song)
{
//cycle thru the tags and grab ids of checked tags
int tagCount = song.Tags.Count;
List<int> tagIds = new List<int>();
for (int i = tagCount - 1; i > -1; i--)
{
Tag tag = song.Tags[i];
if (tag.Selected)
tagIds.Add(tag.Id);
}
song.Tags = null;
if (ModelState.IsValid)
{
_db.Songs.Add(song);
_db.SaveChanges();
int songId = song.Id;
string sql = "INSERT INTO [dbo].[TagSongs] (Tag_Id, Song_Id) VALUES ";
foreach(int tagid in tagIds)
{
sql += "(" + tagid + "," + songId + "),";
}
//remove the last comma
sql = sql.Substring(0, sql.Length - 1);
_db.Database.ExecuteSqlCommand(sql);
return RedirectToAction("Index");
}
SetCategoriesAndTags(song);
return View(song);
}
View:
#for (int i = 0; i < Model.Tags.Count; i++)
{
Tag t = Model.Tags[i];
#Html.CheckBoxFor(m => m.Tags[i].Selected)
<label for="Tags_#i.ToString()__Selected">#t.TagName</label>
#Html.HiddenFor(m => m.Tags[i].Id)
#Html.HiddenFor(m => m.Tags[i].TagName)
}
First off, do not use string concatenation for SQL queries or this will open you up to SQL Injection attack. This code should get you what you need. Call it from your controller ActionMethod.
private void AddSongs(Song song, List<int> tagIds)
{
_db.Songs.Add(song);
foreach(var tagId in tagIds)
{
var tag = _db.Tags.SingleOrDefault(tagId);
if(tag != null) song.Tags.Add(tag);
}
_db.SaveChanges();
}

Categories

Resources