Navigation property is null - asp.net-mvc-5

Album navigation property is null in SellingRequest when I try to load it by include() while it seems every thing is OK!
These are the codes:
public class Album
{
public int Id { get; set; }
public string Note { get; set; }
public virtual SellingRequest SellingRequest { get; set; }
public int? SellingRequestId { get; set; }
public List<Photo> Photos { get; set; }
public virtual MortgageAndRent MortgageAndRent { get; set; }
public int? MortgageAndRentId { get; set; }
}
public class SellingRequest
{
#region Properies
public int Id { get; set; }
public virtual Album Album { get; set; }
public int AlbumId { get; set; }
#endregion Properies
}
Here is where I create album for SellingRequest.
public ActionResult DoUpload(HttpPostedFileBase file, UploadPopupViewModel uploadPopupViewModel)
{
if (file != null && file.ContentLength > 0)
{
string path = Path.Combine(Server.MapPath("~/Contents/Images"), Path.GetFileName(file.FileName));
file.SaveAs(path);
Photo photo = new Photo() { Path = path };
ResponseMessage<Album> album = new ResponseMessage<Album>();
if(uploadPopupViewModel.SellingRequestId!=0)
album = _albumService.GetAlbumBySellingRequestId(uploadPopupViewModel.SellingRequestId);
if (uploadPopupViewModel.MortgageAndRentId != 0)
album = _albumService.GetAlbumByMortgageAndRentId(uploadPopupViewModel.SellingRequestId);
if (album.IsSuccess)
{
photo.AlbumId = album.Result.Id;
}
else
{
Album newAlbum = new Album();
if (uploadPopupViewModel.SellingRequestId != 0)
newAlbum.SellingRequestId = uploadPopupViewModel.SellingRequestId;
if (uploadPopupViewModel.MortgageAndRentId != 0)
newAlbum.MortgageAndRentId = uploadPopupViewModel.MortgageAndRentId;
ResponseMessage<Album> beingSavedAlbum = _albumService.Insert(newAlbum);
ResponseMessage<SellingRequest> sellingRequest = _sellingRequestService.GetById(uploadPopupViewModel.SellingRequestId);
if(sellingRequest.IsSuccess)
{
sellingRequest.Result.AlbumId = newAlbum.Id;
_sellingRequestService.Update(sellingRequest.Result);
}
if(beingSavedAlbum.IsSuccess)
photo.AlbumId = beingSavedAlbum.Result.Id;
}
ResponseMessage<Photo> beingSavedPhoto = _photoService.Insert(photo);
if (beingSavedPhoto.IsSuccess)
{
return RedirectToAction("UploadPopup", "Photo", uploadPopupViewModel);
}
else
{
ModelState.AddModelError("ImageError", beingSavedPhoto.ErrorMessages[0]);
return View("AddPhoto");
}
}
else
{
ModelState.AddModelError("ImageError", "Please choose a photo.");
return View("AddPhoto");
}
}
}
And Here is where I Try to query:
public IEnumerable<TEntity> GET(Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _context.Set<TEntity>();
if (filter != null)
query = query.Where(filter);
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
query = query.Include(includeProperty);
if (orderBy != null)
return orderBy(query).ToList();
else
return query.ToList();
}
And consequently, Here is where I try to load Album by include.
public List<SellingRequest> GetAllSellingRequests()
{
List<SellingRequest> sellingRequests = _sellingRepository.GET(null, includeProperties: "Address,Album.Photos", orderBy: sR => sR.OrderBy(s => s.RegisteredDate).OrderByDescending(s => s.RegisteredDate)).ToList();
return sellingRequests;
}
With this function I have the Address property but Album is null! It also happens vise versa. I mean when I include the sellingRequest from album, it returns me null, as well! This is while I can include all other entities with no problem!
Edit
This is the schema of my table in database:
SellingRequest Table
And this is the picture of Get.
Any suggestion would be appreciated in advance.
Regards

Related

How can i execute filter from our JSON filter JSON?

I have a vue3 datagrid and I want to fill the data in this grid with filter by API. At the same time, I want to send the filter fields in the grid to the API as JSON and execute them according to this filter on the API side. How can I do this with AutoQuery?
[Route("/GetConnectors", "POST")]
public class GetConnectors : QueryDb<Connector>
{
public string Id { get; set; }
public string PageParameterJson { get; set; }
}
public class Connector
{
[PrimaryKey]
[AutoIncrement]
public long PKey { get; set; }
public string Id { get; set; }
public string Name { get; set; }
}
public class PageParameters
{
public string Field { get; set; }
public string Operand { get; set; }
public string Value { get; set; }
public string Type { get; set; }
}
It's an example PageParameter JSON;
[
{
"Field":"Name",
"Operand":"cn"//Contains
"Value":"test",
"Type":"string"
},
{
"Field":"Id",
"Operand":"eq"//Equal
"Value":"2",
"Type":"string"
}
]
public async Task<object> Any(GetConnectors query)
{
using var db = AutoQuery.GetDb(query, base.Request);
var filters = query.PageParameters.FromJson<List<PageParameter>>();
//How can I execute query with for CreateQuery?
var q = AutoQuery.CreateQuery(query, Request, db);
var sql = q.PointToSqlString();
return await AutoQuery.ExecuteAsync(query, q, base.Request, dbConnection);
}
Best Regards
i can't execute dynamic filters from server-side datagrid
The AutoQuery.CreateQuery returns OrmLite's Typed SqlExpression which has a number of filtering options inc .Where(), .And(), .Or(), etc.
So you should be able to populate it with something like:
foreach (var filter in filters)
{
var type = filter.Type switch
{
"string" => typeof(string),
_ => throw new NotSupportedException($"Type {filterType}")
};
var value = filter.Value.ConvertTo(type);
if (filter.Operand == "eq")
{
q.And(filter.Field + " = {0}", value)
}
else if (filter.Operand == "cn")
{
q.And(filter.Field + " LIKE {0}", $"%{value}%")
}
else throw new NotSupportedException(filter.Operand);
}
Note: I've rewritten API to be async as you should never block on async methods.

Adding multiple classes to a shopping cart class .net mvc 5

I'm trying to come up with a car service booking application that allows one to either book a car into a service as well as buy a few parts, which is not essential, but I get an error that reads as follows:
SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.BasketLines_dbo.Parts_PartID". The conflict occurred in database "aspnet-Noir-20190224082924", table "dbo.Parts", column 'PartId'.
The statement has been terminated.
My classes are as follows:
PART
public class Part
{
[Key]
public int PartId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public byte[] ImageFile { get; set; }
public string ImageFilePath { get; set; }
public decimal Price { get; set; }
public virtual ICollection<ServicePartMapping>
ServicePartMappings { get; set;}
}
Service
public class Service
{
public int ServiceId { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public decimal Price { get; set; }
public ICollection<Part> Parts { get; set; }
}
ServicePartMapping
public class ServicePartMapping
{
public int ServicePartMappingID { get; set; }
public int PartNumber { get; set; }
public int? ServiceId { get; set; }
public int? ServicePartId { get; set; }
public virtual Service Service { get; set; }
public virtual ServicePart ServicePart { get;
set; }
}
Basket
public class Basket
{
public int Id { get; set; }
private string BasketID { get; set; }
private const string BasketSessionKey =
"BasketID";
private ApplicationDbContext db = new
ApplicationDbContext();
private string GetBasketID()
{
if
(HttpContext.Current.Session[BasketSessionKey]
== null)
{
if
(!string.IsNullOrWhiteSpace
(HttpContext.Current
.User.Identity.Name))
{
HttpContext.Current
.Session[BasketSessionKey] =
HttpContext.Current
.User.Identity.Name;
}
else
{
Guid tempBasketID = Guid.NewGuid()
HttpContext.Current
.Session[BasketSessionKey]
= tempBasketID.ToString();
}
}
return
HttpContext.Current
.Session[BasketSessionKey].ToString();
}
public static Basket GetBasket()
{
Basket basket = new Basket();
basket.BasketID = basket.GetBasketID();
return basket;
}
public void AddServiceToBasket(int serviceID,
int quantity)
{
var basketLine =
db.BasketLines.FirstOrDefault(b =>
b.BasketID == BasketID && b.ServiceID
== serviceID);
if (basketLine == null)
{
basketLine = new BasketLine
{
ServiceID = serviceID,
BasketID = BasketID,
Quantity = quantity,
DateCreated = DateTime.Now
};
db.BasketLines.Add(basketLine);
}
else
{
basketLine.Quantity += quantity;
}
db.SaveChanges();
}
public void AddPartToBasket(int partID, int
quantity)
{
var basketLine =
db.BasketLines.FirstOrDefault(b =>
b.BasketID == BasketID && b.PartId
== partID);
if (basketLine == null)
{
basketLine = new BasketLine
{
PartId = partID,
BasketID = BasketID,
Quantity = quantity,
DateCreated = DateTime.Now
};
db.BasketLines.Add(basketLine);
}
else
{
basketLine.Quantity += quantity;
}
db.SaveChanges();
}
public void RemoveLine(int ID)
{
var basketLine = db.BasketLines.FirstOrDefault(b => b.BasketID == BasketID && b.ServiceID
== ID || b.PartId == ID);
if (basketLine != null)
{
db.BasketLines.Remove(basketLine);
}
db.SaveChanges();
}
public void UpdateBasket(List<BasketLine> lines)
{
foreach (var line in lines)
{
var basketLine = db.BasketLines.FirstOrDefault(b => b.BasketID == BasketID &&
b.ServiceID == line.ServiceID);
if (basketLine != null)
{
if (line.Quantity == 0)
{
RemoveLine(line.ServiceID);
}
else
{
basketLine.Quantity = line.Quantity;
}
}
}
db.SaveChanges();
}
public void EmptyBasket()
{
var basketLines = db.BasketLines.Where(b => b.BasketID == BasketID);
foreach (var basketLine in basketLines)
{
db.BasketLines.Remove(basketLine);
}
db.SaveChanges();
}
public List<BasketLine> GetBasketLines()
{
return db.BasketLines.Where(b => b.BasketID == BasketID).ToList();
}
public decimal GetTotalCost()
{
decimal basketTotal = decimal.Zero;
decimal serviceTotal = decimal.Zero;
decimal partTotal = decimal.Zero;
if (GetBasketLines().Count > 0)
{
serviceTotal = db.BasketLines.Where(b => b.BasketID == BasketID).Sum(b => b.Service.Price
* b.Quantity);
partTotal = db.BasketLines.Where(b => b.BasketID == BasketID).Sum(b => b.Part.Price
* b.Quantity);
basketTotal = serviceTotal + partTotal;
}
return basketTotal;
}
public int GetNumberOfItems()
{
int numberOfItems = 0;
if (GetBasketLines().Count > 0)
{
numberOfItems = db.BasketLines.Where(b => b.BasketID == BasketID).Sum(b => b.Quantity);
}
return numberOfItems;
}
public void MigrateBasket(string userName)
{
//find the current basket and store it in memory using ToList()
var basket = db.BasketLines.Where(b => b.BasketID == BasketID).ToList();
//find if the user already has a basket or not and store it in memory using ToList()
var usersBasket = db.BasketLines.Where(b => b.BasketID == userName).ToList();
//if the user has a basket then add the current items to it
if (usersBasket != null)
{
//set the basketID to the username
string prevID = BasketID;
BasketID = userName;
//add the lines in anonymous basket to the user's basket
foreach (var line in basket)
{
AddServiceToBasket(line.ServiceID, line.Quantity);
AddPartToBasket(line.PartId, line.Quantity);
}
//delete the lines in the anonymous basket from the database
BasketID = prevID;
EmptyBasket();
}
else
{
//if the user does not have a basket then just migrate this one
foreach (var basketLine in basket)
{
basketLine.BasketID = userName;
}
db.SaveChanges();
}
HttpContext.Current.Session[BasketSessionKey] = userName;
}
public decimal CreateOrderLines(int orderID)
{
decimal orderTotal = 0;
var basketLines = GetBasketLines();
foreach (var item in basketLines)
{
BillLine BillLine = new BillLine
{
Service = item.Service,
ServiceID = item.ServiceID,
ServiceName = item.Service.Name,
Quantity = item.Quantity,
ServicePrice = item.Service.Price,
BillID = orderID
};
orderTotal += (item.Quantity * item.Service.Price);
db.BillLines.Add(BillLine);
}
db.SaveChanges();
EmptyBasket();
return orderTotal;
}
}
BasketLine
public class BasketLine
{
public int ID { get; set; }
public string BasketID { get; set; }
public int ServiceID { get; set; }
public int PartId { get; set; }
[Range(0, 50, ErrorMessage = "Please enter a quantity between 0 and 50")]
public int Quantity { get; set; }
public DateTime DateCreated { get; set; }
public virtual Service Service { get; set; }
public virtual Part Part { get; set; }
}
Assumed that EF Code First is used, the exception message indicates that you're using foreign key constraint inside BasketLines table which references PartId primary key column in Parts table, and you're trying to insert a value into BasketLines.PartId column which not exist in Parts table at this statement:
basketLine = new BasketLine
{
PartId = partID, // this assignment is the problem source
BasketID = BasketID,
Quantity = quantity,
DateCreated = DateTime.Now
};
db.BasketLines.Add(basketLine);
Based from inspection, you're trying to build relationship between Service, Part and BasketLine entities, therefore I suggested to add ForeignKeyAttribute for ServiceId and PartId property in BasketLine entity:
public class BasketLine
{
public int ID { get; set; }
public string BasketID { get; set; }
[ForeignKey("Service")]
public int ServiceID { get; set; }
[ForeignKey("Part")]
public int PartId { get; set; }
[Range(0, 50, ErrorMessage = "Please enter a quantity between 0 and 50")]
public int Quantity { get; set; }
public DateTime DateCreated { get; set; }
public virtual Service Service { get; set; }
public virtual Part Part { get; set; }
}
Additionally, since it's stated that a BasketLine requires Service with optional Part, you may also try modify OnModelCreating() method inside DbContext like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BasketLine>()
.HasOptional(x => x.Part) // can save BasketLine without specifying Part
.WithRequired(x => x.Service); // cannot save BasketLine without using Service
}
Related issues:
Configure One-to-One Relationships in EF Code First
The INSERT statement conflicted with the FOREIGN KEY constraint

The challenge of uploading image. Other information are submitting to the database but the image is not uploading

This is the class of the customer
namespace test2.Models
{
public class Customer
{
public int Id { get; set; }
public string Full_Name { get; set; }
public Driver Driver { get; set; }
[Required]
[Display(Name = "Route")]
public int DriverId { get; set; }
[DataType(DataType.ImageUrl)]
[DisplayName("Driver's License ")]
public string ImageUrl { get; set; }
}
}
Controller
[HttpPost]
public ActionResult Save(Customer customer, HttpPostedFileBase file)
{
if (!ModelState.IsValid)
{
var viewModel = new CustomerFormViewModel
{
Customer = customer,
Drivers = _context.Drivers.ToList()
};
string imageLocation = "";
if ((file == null || file.ContentLength < 1))
{
ViewBag.Msg = "Please select an image";
return View();
}
if (!SaveImg(file, out imageLocation))
{
ViewBag.Msg = "An error occured while saving the image";
}
customer.ImageUrl = imageLocation;
return View("CustomerForm", viewModel);
}
//customer.ImageUrl = imageLocation;
if (customer.Id == 0)
_context.Customers.Add(customer);
else
{
var customerInDb = _context.Customers.Single(d => d.Id == customer.Id);
customerInDb.Full_Name = customer.Full_Name;
customerInDb.DriverId = customer.DriverId;
customerInDb.ImageUrl = customer.ImageUrl;
}
_context.SaveChanges();
return RedirectToAction("Index", "Customers");
}
public bool SaveImg(HttpPostedFileBase file, out string imageLocation)
{
imageLocation = "";
string serverPath = Server.MapPath("~/Images");
if ((file == null || file.ContentLength < 1))
{
//throw an exception showing that no file is present
}
var imageString = file.ToString();
var allowedExtensions = new[]
{
".jpg", ".png", ".jpg", ".jpeg"
};
var fileName = Path.GetFileName(file.FileName); //eg myImage.jpg
var extension = Path.GetExtension(file.FileName); //eg .jpg
if (allowedExtensions.Contains(extension.ToLower()))
{
string ordinaryFileName = Path.GetFileNameWithoutExtension(file.FileName);
string myFile = ordinaryFileName + "_" + Guid.NewGuid() + extension;
var path = Path.Combine(serverPath, myFile);
file.SaveAs(path);
string relativePath = "~/Images/" + myFile;
imageLocation = relativePath;
return true;
//return a success message here
}
else
{
//file save error
return false;
}
}
Include the file as part of the model:
public class Customer
{
public int Id { get; set; }
public string Full_Name { get; set; }
public Driver Driver { get; set; }
[Required]
[Display(Name = "Route")]
public int DriverId { get; set; }
[DataType(DataType.ImageUrl)]
[DisplayName("Driver's License ")]
public string ImageUrl { get; set; }
[NotMapped]
public HttpPostedFileBase ImageFile { get; set; }
}
Reference in the view like so:
#using (Html.BeginForm("Save", "Image", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
#Html.TextBoxFor(model => model.ImageFile, new { htmlAttributes = new { #class = "form-control" }, type = "file" })
</div>
The not mapped property will ensure it is ignored in the db context. It can then be accessed using:
[HttpPost]
public bool Save(Customer customer)
{
if (customer.ImageFile != null)
{
// do something
}
}
It wouldn't be good practise to save the file to the database. Instead, store it in the project directory and either store the name or the image of the path to the image in the database.

Create a DropDown List from a db Entity MVC5

I want to create a dropdown list based on the contents of a db entity.
This seems like a simple enough concept but I can't really seem to pin it down.
Here's my code:
MODEL
public partial class Escuela
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Escuela()
{
this.Empleadoes = new HashSet<Empleado>();
}
public int ID { get; set; }
public string Nombre { get; set; }
public int PuestoID { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Empleado> Empleadoes { get; set; }
public virtual Puesto Puesto { get; set; }
}
public partial class ESCUELAEntities : DbContext
{
public ESCUELAEntities()
: base("name=ESCUELAEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Alumno> Alumnoes { get; set; }
public virtual DbSet<Empleado> Empleadoes { get; set; }
public virtual DbSet<Escuela> Escuelas { get; set; }
public virtual DbSet<Grupo> Grupoes { get; set; }
public virtual DbSet<Puesto> Puestoes { get; set; }
}
CONTROLLER
public ActionResult Index()
{
// HAVE TRIED THESE THREE
// #1
var EscQry = from d in db.Escuelas
select d.Nombre;
var escuelas = new SelectList(EscQry, "ID", "Nombre");
ViewData["esc"] = escuelas;
// #2
var escuelas = new SelectList(from d in db.Escuelas
select new SelectListItem { Text = d.Nombre, Value = d.ID.ToString() });
ViewData["esc"] = escuelas;
// #3
IEnumerable<Escuela> model = from p in db.Escuelas
select new Escuela { Nombre = p.Nombre };
// #1
return View();
// #2
return View();
// #3
return View(model);
}
VIEW
#model IEnumerable<_3E_III.Models.Escuela>
#{
ViewBag.Title = "Home Page";
}
#Html.DropDownList("Escuelas", ViewData["esc"] as List<SelectListItem>)
I get this error.
There is no ViewData item of type 'IEnumerable' that has the key 'Escuelas'.
I would make a View Model of the domain class, based on what properties I would need to show in my view.
public class EscuelaViewModel
{
public int ID { get; set; }
public string Nombre { get; set; }
public int PuestoID { get; set; }
.............. etc.
public Collection<SelectListItem> Escuelas {get; set;}
private static Collection<SelectListItem> CreateEscuelasOptions(string selectedOption == "")
{
var model = from p in db.Escuelas select new Escuela { Number = p.Nombre, Id= p.Id };
var options = new Collection<SelectListItem>();
foreach(var esc in model)
options.Add(new SelectListItem {Value = esc.Id, Text = esc.Number, Selected = selectedOption.Equals(esc.Number)});
return options;
}
public void LoadViewData()
{
Escuelas = CreateEscuelasOptions(Nombre);
}
}
Then, in the Controller:
public ActionResult Index()
{
var EscuelaViewModel = new EscuelaViewModel();
EscuelaViewModel.LoadViewData();
return View(EscuelaViewModel);
}
And the View:
#model EscuelaViewModel
#{
ViewBag.Title = "Home Page";
}
#Html.DropDownListFor(x => x.Nombre, Model.Escuelas, --Select option--)

C# 4.0 Entity Framework ExecuteStoreQuery:There is already an open DataReader

I use ExecuteStoreQuery and make an IEnumerable<> list. When I get this list with foreach and use some linq query in this area it give a this error :
There is already an open DataReader associated with this Connection which must be closed first.
What must I do for this ?
My code looks like that :
//IEnumerable function
public IEnumerable<NewTable> YirmiAjansTweetList()
{
string nativeSQLQuery = "Select t1.id,t1.baslik,t1.url,t1.gtarih,t3.ck,t3.cs,t2.token,t2.tokensecret from yirmiajanstweets t1 join uyeler t2 ON(t1.uid=t2.u_id) join uygulamalar t3 ON(t2.uyid=t3.u_id) where t1.gtarih is not null and t1.durum=0 and t1.gtarih<Now();";
IEnumerable<NewTable> newList = db.ExecuteStoreQuery<NewTable>(nativeSQLQuery, System.Data.Objects.MergeOption.NoTracking);
if (newList != null)
{
return newList;
}
else
{
return null;
}
}
public class NewTable
{
public int id { get; set; }
public string baslik { get; set; }
public string url { get; set; }
public DateTime gtarih { get; set; }
public string ck { get; set; }
public string cs { get; set; }
public string token { get; set; }
public string tokensecret { get; set; }
}
//look for a record function
public yirmiajanstweets YirmiAjansKayitBak(int _id)
{
yirmiajanstweets ya = db.yirmiajanstweets.FirstOrDefault(f => f.id == _id);
if (ya != null)
{
return ya;
}
else
{
return null;
}
}
//i get this list like that with foreach
IEnumerable<dynamic> ya = yaBLL.YirmiAjansTweetList().AsEnumerable();
if (ya != null)
{
foreach (var item in ya)
{
//when read this line give error
var myRecord = YirmiAjansKayitBak(item.id);
}
}
else
{
Response.Write("Not found !");
}
Try to add MultipleActiveResultSets=true to your connection string.
Try to load the query result into a list before you iterate over the collection:
IEnumerable<dynamic> ya = yaBLL.YirmiAjansTweetList().ToList();

Resources