Last inserted id with EF 4.1 , MVC 3 - c#

I'm using asp.net mvc 3 and EF 4.1 with visual studio 2010 and im new to it.
i have a problem about last inserted id. i have two table in my db "points_Order" and "points_OrderDetails".
db.Order.Add(po);
db.SaveChanges();
//second thing i have tried
var orderID = (from oi in db.Order
select oi.ID)
.Max(i => i);
// and this first thing
pod.OrderID = po.ID;
pod.OrderID = orderID;
db.OrderDetails.Add(pod);
db.SaveChanges();
context class:
public class points_Order {
[Key]
public int ID { get; set; }
public string Owner { get; set; }
public DateTime Date { get; set; }
public byte Status { get; set; }
public int Total { get; set; }
//public virtual points_OrderDetails OrderDetail { get; set; }
}
public class points_OrderDetails {
[Key]
public int OrderID { get; set; }
public string OrderType { get; set; }
public int Amount { get; set; }
public int ItemID { get; set; }
public int ItemRecord { get; set; }
public string ItemCode { get; set; }
public byte Plus { get; set; }
public byte Degree { get; set; }
public string Kind { get; set; }
public string Sex { get; set; }
public string Race { get; set; }
public string Tier { get; set; }
public string SetItem { get; set; }
public string SOX { get; set; }
//public Blues Blue { get; set; }
}
public DbSet<points_Order> Order { get; set; }
public DbSet<points_OrderDetails> OrderDetails { get; set; }
im getting the error "{"Cannot insert the value NULL into column 'OrderID', table 'db.dbo.points_OrderDetails'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}"
what can i do? am i doing something wrong?

If you define a relationship from order -> order details in your model, it should work like this:
po.Details.Add(pod); // or pod.Order = po;
db.Order.Add(po);
db.SaveChanges();
EF should figure out the relations for you, no need to set ID's manually.
UPDATE: you're trying to do something that is not supported. You have a one-to-one mapping; EF does not support it the way you intend to (shared primary key). See http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first-part-5-one-to-one-foreign-key-associations.aspx for an explanation on how to model one-to-one in EF.

Related

Why is my Entity Framework Many to Many Table not saving automatically?

I have to classes, VisitModel and VisitorModel, A visitModel can have many VisitorModel and vice versa. After adding both relationship to the modelBuilder, its still not saving to the third auto-generated table. It created the table, but when I try to save, it does not save both Ids. Here is my code:
public class VisitorModel
{
public int VisitorModelId { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
public bool IsDeleted { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string PhotoUrl { get; set; }
public string Address { get; set; }
public int BranchId { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public virtual ICollection<VisitModel> VisitModels { get; set; }
}
and here is the VisitModel class:
public class VisitModel
{
public VisitModel()
{
VisitorModels = new List<VisitorModel>();
}
public int VisitModelId { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateModified { get; set; }
public bool IsDeleted { get; set; }
public string UserToVisit { get; set; }
public virtual User User { get; set; }
public string HostEmail { get; set; }
public int UserId { get; set; }
public int VisitorTypeId { get; set; }
public int PurposeOfVisitId { get; set; }
public string OtherPurposeOfVisit { get; set; }
public DateTime ArrivalDate { get; set; }
public DateTime ArrivalTime { get; set; }
public DateTime DepartureTime { get; set; }
public DateTime DepartureDate { get; set; }
public bool IsCheckedIn { get; set; }
public bool IsCheckedOut { get; set; }
public string BookedBy { get; set; }
public bool IamHost { get; set; }
public virtual ICollection<VisitorModel> VisitorModels { get; set; }
}
And this is the modelBuilder:
modelBuilder.Entity<VisitModel>()
.HasMany(up => up.VisitorModels)
.WithMany(course => course.VisitModels)
.Map(mc =>
{
mc.ToTable("VisitVisitorModel");
mc.MapLeftKey("VisitModelId");
mc.MapRightKey("VisitorModelId");
});
When I try to save, it does not save both Ids to the VisitVisitorModel table. The table is always empty. Please what am I doing wrong?
Because you followed the entity framework many-to-many conventions, you don't need a fluent API part to design a junction table.
Entity framework knows, just by looking at your class definitions, that you designed a many-to many relation. Entity Framework will design a proper junction table for you. You should not even mention this junction table in your dbContext:
class MyDbContext : DbContext
{
public DbSet<VisitModel> VisitModels {get; set;}
public DbSet<VistitorModel> VistiroModels {get; set}
}
But if I have no DbSet for my junction table, how can I do my joins on VisitModel and VisitorModel?
The answer is: don't use joins, use the ICollections;
Give me Names and Address of all VisitorModels that are not deleted togeter with all the arrival times and departure times of their VisitModels that have checked in Today
Normally you would join VisitorModel with the junction table VisitVisitorModel on VisitModelId and join again on VisitModel on VisitorModelId.
But you could also use the ICollectioins:
var result = myDbContext.VisitorModels
.Where(visitorModel => !visitorModel.IsDeleted)
.Select(visitorModel => new
{
// select only the properties of visitorModel you will be using:
FullName = visitorModel.FullName,
Address = visitorModel.Address,
Phone = visitorModel.Phone,
... // other properties
// get ArrivalTime and DepartureTime of all VisitModels that are checked in
VisitModels = visitorModel.VisitModels
.Where(visitModel => visitModel.IsCheckedInd)
.Select(visitModel => new
{ // again: select only the properties you will be using:
ArrivalTime = visitModel.ArrivalTime,
DepartureTime = visitModel.DepartureTime,
... // other properties
})
.ToList(),
}
}
Because of the proper many-to-many configuration you won't need the junction table, and you won't need to do joins with primary keys and foreign keys. Entity framework will know which joins to do.

ServiceStack OrmLite mapping with references not working

I'm trying out OrmLite to see if I can replace Entity Framework in my projects. The speed is quite significant on simple queries. But I tried to map/reference a [1 to many- relation and read the documentation + examined the test code from the github page but without success. This is my example. Is there something I've forgot or should do to get it working like Entity Framework?
Example
// EF: returns +15.000 records + mapped > product.StockItems (slow)
dbContext.Products.Include(x => x.StockItems).ToList();
// OrmLite: returns +100.000 records (NO mapping > product.StockItems)
db.Select<Product>(db.From<Product>().Join<StockItem>());
// OrmLite: +15.000 separate requests to sql server (bad workarround + slow)
foreach (var product in db.Select<Product>())
{
// manual mapping
product.StockItems = db.Select<StockItem>(x => x.ProductId == product.Id);
}
Product.cs
public class Product
{
public int Id { get; set; }
public ProductType ProductType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool LimitedToStores { get; set; }
public string Sku { get; set; }
public decimal Price { get; set; }
public decimal OldPrice { get; set; }
public decimal SpecialPrice { get; set; }
public decimal DiscountPercentage { get; set; }
public DateTime? DateChanged { get; set; }
public DateTime? DateCreated { get; set; }
//...
[Reference]
public virtual IList<StockItem> StockItems { get; set; } = new List<StockItem>();
}
StockItem.cs
public class StockItem
{
public int Id {get; set;}
[References(typeof(Product))]
public int ProductId { get; set; }
public string Size { get; set; }
public int TotalStockQuantity { get; set; }
public string Gtin { get; set; }
public int DisplayOrder { get; set; }
// ...
[Reference]
public virtual Product Product { get; set; }
}
Ideally your POCOs/DTOs shouldn't use interfaces and you don't need to use virtual as ORM only populates your own POCOs (i.e. it doesn't create proxies of your models like other Heavy ORMs), I also prefer to use [AutoIncrement] for integer Ids (unless you need to populate specific Ids) so my Models would look like:
public class Product
{
[AutoIncrement]
public int Id { get; set; }
public ProductType ProductType { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int DisplayOrder { get; set; }
public bool LimitedToStores { get; set; }
public string Sku { get; set; }
public decimal Price { get; set; }
public decimal OldPrice { get; set; }
public decimal SpecialPrice { get; set; }
public decimal DiscountPercentage { get; set; }
public DateTime? DateChanged { get; set; }
public DateTime? DateCreated { get; set; }
[Reference]
public List<StockItem> StockItems { get; set; }
}
public class StockItem
{
[AutoIncrement]
public int Id { get; set; }
[References(typeof(Product))]
public int ProductId { get; set; }
public string Size { get; set; }
public int TotalStockQuantity { get; set; }
public string Gtin { get; set; }
public int DisplayOrder { get; set; }
}
OrmLite's POCO References only populate 1-level deep and it's not a good idea to have cyclical relationships as they're not serializable so I'd remove the back reference on StockItems as it's not going to be populated.
You also need to use LoadSelect in order to query and return POCOs with references, so to return Product with their StockItem references you can just do:
db.LoadSelect<Product>();
You can also populate this manually with 2 queries by using Merge extension method to merge 2 disconnected record sets, e.g:
var q = db.From<Product>().Join<StockItem>();
var products = db.Select(q.SelectDistinct());
var stockItems = db.Select<StockItem>();
products.Merge(stockItems);
Which will merge Products with their StockItems which you can quickly see by running:
products.PrintDump();

How to create a foreign relation to one Model from multiple other models using Entity framework?

I am trying to create my first app using ASP.NET MVC framework and Entity Framework 6.
I chose to use code first approach and I started by defining my Models.
I have a model called Client with an identity attribute called Id. I have multiple Models that has an attribute called ClientId. The ClientId attribute should have virtual link to the Clients Model.
Here is how my Client model looks like
[Table("clients")]
public class Client
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string status { get; set; }
public DateTime created_at { get; set; }
public DateTime? modified_at { get; set; }
public Client()
{
status = "Active";
created_at = DateTime.UtcNow;
}
}
Then here is how I am creating a belong to relation using other models.
[Table("BaseClientsToUsers")]
public class ClientToUser : ModelDefault
{
[ForeignKey("User")]
public int UserID { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
[ForeignKey("Team")]
public int DefaultTeamId { get; set; }
public DateTime? JoinedAt { get; set; }
public bool IsActive { get; set; }
public virtual User User { get; set; }
public virtual Client Client { get; set; }
public virtual Team Team { get; set; }
public ClientToUser()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
[Table("BaseTeams")]
public class Team : ModelDefault
{
[MaxLength(250)]
public string Name { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
public bool IsActive { get; set; }
public virtual Client Client { get; set; }
public Team()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
}
But, when I try to update my databases I get the following error
Introducing FOREIGN KEY constraint
'FK_dbo.BaseTeams_dbo.BaseClients_ClientId' on table 'BaseTeams' may
cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or
ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could
not create constraint or index. See previous errors.
I am not really sure what could be causing the error but it seems it is because I am creating multiple Foreign keys to the same `Clients model.
How can I fix this error?
Hello #Mike A When I started MVC I got this error too, so you need aditional tables that connects your DB items.
So try connect your database items with tables like that:
Here is my working example:
[Table("Products")]
public class Product
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal InternalPrice { get; set; }
public string Url { get; set; }
}
[Table("Categories")]
public class Category
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Url { get; set; }
}
[Table("ProductCategories")]
public class ProductCategory
{
[Key]
[Column(Order = 0)]
public string ProductId { get; set; }
[Key]
[Column(Order = 1)]
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
So you can connect your items without problems hope this will help you.

Save complexa data using entity framework

Hi every one I want to save complex data using Entity Framework and C#. I have 2 classes Product and Order defined as follows
Product Class
public class Product
{
[Key]
public int Id { get; set; }
public string SKU_Code { get; set; }
public string Product_Name { get; set; }
public string Quantity { get; set; }
public string Price { get; set; }
public string Image { get; set; }
public DateTime Created_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
Order Class
public class Order
{
[Key]
public long ID { get; set; }
public string Order_Id { get; set; }
public string Payment_Type { get; set; }
public string Customer_Name { get; set; }
public string Shipping_Address { get; set; }
public DateTime Order_Date { get; set; }
public DateTime Modified_Date { get; set; }
public bool Flag { get; set; }
public List<Product> ProductDetails { get; set; }
}
And I want to save data Order details and my piece of code is as follows.
public Order Add(Order odrerDetails)
{
using (var context = new EcommerceDBContext())
{
var MyOrder_Id = Helper.Random(7); //Generate random orderID from my class
foreach (var detail in odrerDetails.ProductDetails)
{
odrerDetails.Order_Id = MyOrder_Id;
odrerDetails.Quantity = Convert.ToInt32(detail.Quantity);
odrerDetails.Amount = Convert.ToDouble(detail.Price);
//Other Details
context.objOrderListing.Add(odrerDetails);
}
context.SaveChanges();
return odrerDetails;
}
}
This gives me perfect data but when it comes to context.SaveChanges(); it return's me error.
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types.
To me you domain model seems all wrong. The order should just be used for grouping, its a typical e-commerce scenario.
When you get a receipt of your purchases, you get one receipt with every Item and price listed next to it. Its considered as one order of multiple things, not multiple orders of multiple things.
Reading your last comment, you cant have multiple orders with the same order id. Try to understand the domain first before trying to solve it with code. Also,you have no notion of a Customer with an Order.
public class Product
{
[Key]
public int Id { get; set; }
public string SKU_Code { get; set; }
public string Product_Name { get; set; }
public string Price { get; set; }
public string Image { get; set; }
public DateTime Created_Date { get; set; }
public DateTime Modified_Date { get; set; }
}
public class Order
{
[Key]
public long ID { get; set; }
public string Order_Id { get; set; }
public string Payment_Type { get; set; }
public string Customer_Name { get; set; }
public string Shipping_Address { get; set; }
public DateTime Order_Date { get; set; }
public DateTime Modified_Date { get; set; }
public bool Flag { get; set; }
public List<OrderLineItem> Items { get; set; }
}
public class OrderLineItem
{
[Key]
public long ID { get; set; }
public long Order_Id { get; set; }
public long Product_Id {get; set;}
public int Quantity {get; set;}
}

Only mapping to subset of a table

Weird question here.
I have a bad situation with a database I can't change.
[Table("PROJTABLE")]
public class Certifikat {
[Key]
public long Recid { get; set; }
public String DATAAREAID { get; set; }
public String Projid { get; set; }
public virtual StandardAndScope StandardInfo { get; set; }
}
[Table("DS_CRT_PROJSTANDARDSCOPE")]
public class StandardAndScope {
[Key]
public long RECID { get; set; }
public String DATAAREAID { get; set; }
public String Standard { get; set; }
public String Scope { get; set; }
}
I have an optional one-to-many relationship from Certifikat to StandardAndScope. However! It's only one-to-many if the DATAAREAID column is a certain value ("crt").
Do I have any way of telling EntityFramework only to map rows where the value of that column is crt?

Categories

Resources