I am trying to update a CART. When I am doing the search for it, it fails. It used a GUID since the user is not logon. I don't know if I have to re-update the DBEntities maybe ? not sure.
I got this error : The specified type member 'CartId' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
Thanks
ShoppingCart.cs
namespace Tp1WebStore3.Models
{
public partial class ShoppingCart
{
Tp1WebStoreDBEntities db = new Tp1WebStoreDBEntities();
string ShoppingCartId { get; set; }
public const string CartSessionKey = "CartId";
public static ShoppingCart GetCart(HttpContextBase context)
{
var cart = new ShoppingCart();
cart.ShoppingCartId = cart.GetCartId(context);
return cart;
}
// Helper method to simplify shopping cart calls
public static ShoppingCart GetCart(Controller controller)
{
return GetCart(controller.HttpContext);
}
public void AddToCart(Produit produit)
{
// Get the matching cart and album instances
var cartItem = db.Paniers.SingleOrDefault(
c => c.CartId == ShoppingCartId &&
c.ProduitId == produit.ProduitId); <== the error happen here
Panier.cs
namespace Tp1WebStore3.Models
{
using System;
using System.Collections.Generic;
public partial class Panier
{
public int PanierId { get; set; }
public string CartId { get; set; }
public int ProduitId { get; set; }
public int Quantite { get; set; }
public decimal Prix { get; set; }
public System.DateTime DateCree { get; set; }
public virtual Produit Produit { get; set; }
}
}
produit.cs
namespace Tp1WebStore3.Models
{
using System;
using System.Collections.Generic;
public partial class Produit
{
public Produit()
{
this.Paniers = new HashSet<Panier>();
}
public int ProduitId { get; set; }
public int CategorieId { get; set; }
public string Description { get; set; }
public int Quantite { get; set; }
public decimal Prix { get; set; }
public virtual Categorie Categorie { get; set; }
public virtual ICollection<Panier> Paniers { get; set; }
}
}
If you changed things in the database you have to update the Data model. Right click inside your .edmx file where your entity diagram is and click Update model from db
Related
I have issue that I hope someone here will be able to help me.For this exercise I`m using aspnetboilerplate framework.
So I create 3 entity and they ALL work good (at least I guess they work good)
Little bit recap of project
One Recepie HAVE one or more Ingredient
Ingrident.cs
public class Ingrident : Entity
{
public string Name { get; set; }
public Master Master { get; set; }
public int? MasterId { get; set; }
public Recepie Recepie { get; set; }
public int? RecepieId { get; set; }
}
Master.cs
public class Master : Entity
{
public string Name { get; set; }
public string? Image { get; set; }
public string? ShortDescription { get; set; }
public string? FullDescription { get; set; }
public string? Keywords { get; set; }
public string Slug { get; set; }
public int? Count { get; set; }
public List<Ingrident> Ingridents { get; set; }
}
Recepie.cs
public class Recepie : Entity
{
public string RecepieName { get; set; }
public Ingrident Ingridents { get; set; }
}
With this database structure I can add Recepie and add only one ingredient when I try to send [] of Ingredient its show me DTO error.
And here is RecepieAppService.cs
public class RecepieAppService : AsyncCrudAppService<IndexIngrident.Entities.Recepie,RecepieDto>
{
private readonly IRepository<IndexIngrident.Entities.Recepie> _repository;
private readonly IRepository<IndexIngrident.Entities.Ingrident> _ingRepository;
public RecepieAppService(IRepository<IndexIngrident.Entities.Recepie> repository, IRepository<IndexIngrident.Entities.Ingrident> ingRepository)
: base(repository)
{
_repository = repository;
_ingRepository = ingRepository;
}
public List<RecepieFullGetDto> GetAllIncluded()
{
var result = _repository.GetAllIncluding(x => x.Ingridents , x => x.Ingridents.Master);
Debug.WriteLine(result);
return ObjectMapper.Map<List<RecepieFullGetDto>>(result);
}
}
RecepieDto.cs
[AutoMap(typeof(IndexIngrident.Entities.Recepie))]
public class RecepieDto : EntityDto
{
public string RecepieName { get; set; }
public IngridentRecepieDto Ingridents { get; set; }
}
public class IngridentRecepieDto : EntityDto
{
public string Name { get; set; }
public int RecepieId { get; set; }
}
Using AsyncCrudAppService my CRUD is automatically generated and I`m able to create new Recepie but when I try to do something like this
I get error
you need to add the mapping of objects in both directions, [AutoMapTo (typeof (RecepieDto))] and [AutoMapFrom (typeof (Recepie))], and verify that you have the class, inherits AutomapperProfile
I have 2 entities like below;
public class Order
{
public int Id { get; set; }
public Description { get; set; }
public virtual Purchase Purchase{ get; set;}
}
public class Purchase
{
public int Id { get; set; }
public Description { get; set;}
public int? OrderId { get; set;}
public virtual Order Order { get; set;}
}
Here I create order first.
Based on order i can create purchase.
Purchase can be happened without order also. So it is Nullable foreign key.
For one order, it should have only one purchase. So OrderId is unique also.
How can i specify this relationship in Code First
You can specify a unique attribute like this. You just can't make a unique index the target of a foreign key in EF6.
public class Order
{
public int Id { get; set; }
public string Description { get; set; }
public virtual Purchase Purchase { get; set; }
}
public class Purchase
{
public int Id { get; set; }
public string Description { get; set;}
[Index(IsUnique = true)]
public int? OrderId { get; set; }
public virtual Order Order { get; set; }
}
But EF won't allow a 1-1 relationship to a non-key column, but something like this has the desired relational model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp5
{
public class Order
{
public int Id { get; set; }
public string Description { get; set; }
internal ICollection<Purchase> Purchases { get; } = new HashSet<Purchase>();
public Purchase Purchase { get { return Purchases.FirstOrDefault(); } }
}
public class Purchase
{
public int Id { get; set; }
public string Description { get; set; }
[Index(IsUnique = true)]
public int? OrderId { get; set; }
[ForeignKey("OrderId")]
public virtual Order Order { get; set; }
}
public class Db : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<Purchase> Purchases { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().HasMany(o => o.Purchases).WithOptional(p => p.Order);
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<Db>());
int OrderId;
using (var db = new Db())
{
var o = db.Orders.Create();
o.Description = "New Order";
var p = db.Purchases.Create();
p.Order = o;
p.Description = "New Purchase";
db.Orders.Add(o);
db.Purchases.Add(p);
db.SaveChanges();
OrderId = o.Id;
}
using (var db = new Db())
{
var p = db.Purchases.Create();
p.OrderId = OrderId;
p.Description = "Another Purchase";
db.Purchases.Add(p);
db.SaveChanges(); //fails
}
}
}
}
David
In the comments to your question, you indicated:
I need to make it (OrderId) unique also
You cannot do that that because EF does not support unique columns except keys.
You may use an index which will allow you to make the index unique but you cannot have a unique key.
I am using entity-framework in mvc. I am receiving this error while generating view.I am using MVC controller with read/write actions and views, using EF. I am Trying to generate a list using scaffold template.
This Entity Framework auto generated class
namespace WebApplication3.Models
{
using System;
using System.Collections.Generic;
public partial class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public Nullable<System.DateTime> DOB { get; set; }
public Nullable<int> DepartmentId { get; set; }
public virtual TblDepartment TblDepartment { get; set; }
}
}
Here is my Controller Code :
public ActionResult EmployeesByDep()
{
var employees = db.Employees.Include("TblDepartment").GroupBy(x => x.TblDepartment.DepName)
.Select(y => new TotalDepartments
{
DepName = y.Key,
Total = y.Count()
}
).ToList().OrderByDescending(y=>y.Total);
return View(employees);
}
Model Code:
public string DepName { get; set; }
public int Total { get; set; }
The problem is because you had not declared a key.
You should create a new class EmployeeMetaData.cs
With:
[MetadataType(typeof(EmployeeMetaData))]
public partial class Employee
{
}
public class Employee
{
[Key]
public int EmployeeId { get; set; }
}
add: using System.ComponentModel.DataAnnotations;
I have two EF models -
public class What
{
[Key]
public int primary_key_What { get; set; }
public int another_column_What { get; set; }
public virtual ICollection<Why> Whys { get; set; }
}
And
public class Why
{
[Key]
public int primary_key_Why { get; set; }
public int some_column_Why { get; set; }
public virtual What What { get; set; }
}
The problem is, I have to use another_column_What and some_column_Why for navigating between the two. As you can see none of them are keys or declared unique in the database, also their names are different.
I've tried all the ways I could imagine of and found on search, but none of them works. How and in which model mapping do I use to say, navigate between What and Why using another_column_What and some_column_Why columns.
So whenever a query is generated by EF, it will compare another_column_What with some_column_Why?
Very unfortunately, changing the database architecture (or even column names) is not an option here.
Can anyone please help me with it?
This should work:
Db schema:
What model:
[Table("what")]
public class what
{
[Key]
[Column("primary_key_what")]
public int primary_key_what { get; set; }
[Column("another_column_what")]
public int another_column_what { get; set; }
public virtual ICollection<why> whys { get; set; }
}
Why model:
[Table("why")]
public class why
{
[Key]
[Column("primary_key_why")]
public int primary_key_why { get; set; }
[ForeignKey("what")]
[Column("some_column_why")]
public int some_column_why { get; set; }
public virtual what what { get; set; }
}
Context:
public class Context : DbContext
{
public virtual DbSet<what> what { get; set; }
public virtual DbSet<why> why { get; set; }
public Context() : base("name=SqlConnection")
{
}
}
Main:
static void Main(string[] args)
{
using (var context = new Context())
{
var results = from w in context.what
select w;
foreach (var what in results)
{
Console.WriteLine("what.primary_key_what = {0}", what.primary_key_what);
Console.WriteLine("what.another_column_what = {0}", what.another_column_what);
Console.WriteLine("what has {0} whys", what.whys.Count);
foreach (var why in what.whys)
{
Console.WriteLine("Why.primary_key_why = {0}", why.primary_key_why);
Console.WriteLine("Why.some_column_why = {0}", why.some_column_why);
}
}
}
}
What data:
Why data:
Output:
So I have a model:
[Table("Site")]
public class Store : MPropertyAsStringSettable {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public int CompanyID { get; set; }
public bool IsActive { get; set; }
public string Address { get; set; }
public string City { get; set; }
[Display(Name = "Province")]
public int ProvinceID { get; set; }
public string Postal { get; set; }
public string Phone { get; set; }
public int StoreNumber { get; set; }
public bool visible { get; set; }
public DateTime lastShift { get; set; }
}
The field lastShift is from a different table called "Shifts", how do I get it from that table?
EDIT: The lookup will have to be something like this:
select top 1 shiftDate as lastShift from [Shifts] where SiteID = Store.ID
This is how I load my data:
public class MyDbContext: DbContext {
public MyDbContext()
: base("name=DefaultConnection") {
}
public DbSet<UserAccount> UserAccounts { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Store> Stores { get; set; }
public DbSet<ProvinceModel> Provinces { get; set; }
}
And this is how I use it:
MyDbContext database = new MyDbContext();
var myStores = from database.Stores select ID;
EDIT according to your last edit, this is not the case
It will need to be a "navigation property" which means that you'll need to have an explicit (Foreing Key) relationship between Site and Ship
Then you'll have something like this
Store.Shift.LastShift
But if it is a one to many relationship (and LastShift field is not part of Shift table) then
you'll need to do it manually, and use a view model or a custom property that it is not mapped directly to the table and do the assignment somewhere in your code
If you're using a Repository, then you'll need to add a method there to get the last shift
Then (or if you are using ORM directly) you use the code that #Cristi posted, just remember to add the sorting
public ActionResult MyAction(){
var store = db.Stores.Where(x => x.ID == objId).Select(x => new StoreModel(){
Name = x.Name,
ID = x.ID,
lastShift = db.Shifts.FirstOrDefault(y => y.SiteID == x.ID).OrderByDescending(shift => shift.Date);
}).FirstOrDefault();
return View(store);
}
Here is how I solved the problem.
TL,DR: I shared my dbcontext in my controller so I have access to it in my models!
I manually load the lastShiftTime in my Store Model with the following code:
public class Store : MPropertyAsStringSettable {
.......
public DateTime lastShiftTime {
get{
MyDbContext curContext = MyWebProject.Controllers.MyBaseController.database;
if (curContext != null) {
return (from shift in curContext.Shifts where shift.SiteID == ID select shift.ShiftDate).First();
} else {
return new DateTime(0);
}
}
}
}
Here is my Shift Model I created for this, very standard:
[Table("Shifts")]
public class Shift : MPropertyAsStringSettable {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public int SiteID { get; set; }
public string ShiftID_In_POS { get; set; }
public DateTime ShiftDate { get; set; }
}
And here is how I am sharing the context in controller:
public class MyBaseController : Controller {
.........
private static MyDbContext _database;
public static MyDbContext database {
get {
if (_database == null) {
_database = new MyDbContext();
}
return _database;
}
}
}