update database in asp.net - c#

i'm biulding a web application and when the users log in and trying to buy somthing from web for another time this error apears
SqlException: Cannot insert explicit value for identity column in table 'orderFactors' when IDENTITY_INSERT is set to OFF.
public IActionResult AddToCart(int itemId)
{
var product = _context.Products.Include(p => p.Item).SingleOrDefault(p => p.ItemId == itemId);
if (product != null)
{
int userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier).ToString());
var order = _context.orderFactors.FirstOrDefault(o => o.UserId == userId && !o.IsFinally);
if (order != null)
{
var orderDetail = _context.orderDetails.FirstOrDefault(o => o.OrderId == order.OrderId && o.ProductId == product.Id);
if (orderDetail != null)
{
orderDetail.Count += 1;
}
else
{
_context.orderFactors.Add(order);
_context.orderDetails.Add(new OrderDetail()
{
OrderId = order.OrderId,
ProductId = product.Id,
price = product.Item.Price,
Count = 1
});
}
}
else
{
order = new OrderFactor()
{
IsFinally = false,
CreateDate= DateTime.Now,
UserId= userId
};
_context.orderFactors.Add(order);
_context.SaveChanges();
_context.orderDetails.Add(new OrderDetail()
{
OrderId = order.OrderId,
ProductId = product.Id,
price = product.Item.Price,
Count = 1
});
}
_context.SaveChanges();
}
return RedirectToAction("ShowCart");
}

You are reading from the DB here
var order = _context.orderFactors.FirstOrDefault(o => o.UserId == userId && !o.IsFinally);
But then you try to add the value again here if orderDetail is not null
_context.orderFactors.Add(order);
The order object that you have read will have an Id and therefore the DB thinks you are trying to add the same Id to that table.

Without seeing exactly how you are inserting/updating this it is tough to answer. That said, the error message is fairly explanatory (for once!). You are trying to enter a value into an identity/primary key field. That field is (most likely) auto generated/incremented by your database to guarantee uniqueness.
Somewhere in your saveChanges funtion you are either inserting (most likely) an ID or you are trying to update an ID. If those are marked identity, they cannot be altered unless you set IDENTITY_INSERT ON.
Double check your saveChanges model and the query behind it to make sure you're not trying to update/change/insert your primary key value.

Related

Referring to an entity in another context - Entity Framework

I am trying to use Any method to achieve exists functionality in Entity Framework but when I refer to another entity in the current context, I get an error
The name OrderNumber does not exists in current context
How can I fix this?
var ordResults = from ord in orders
select new Order
{
OrderId = ord.OrderId,
WarehouseId = ord.WarehouseId,
OrderNumber = ord.OrderNumber,
CustomerPoNumber = ord.CustomerPoNumber,
ShipToCode = ord.ShipToCode,
ShipToName = ord.ShipToName,
OrderDate = ord.OrderDate,
PromisedDate = ord.PromisedDate,
if (aadContext.TransactionLogs.Any(t => t.ControlNumber == **OrderNumber** && t.TransactionType == "670")) {"C"} else {"D"},
ord.Status,
ord.CustomerName,
}
You could also try something like this.
I still dont understand what {"C"} else {"D"} if its condition you could add that like
t.somevalue=="C" || t.SomeValue=="E"
var ordResults = from ord in orders
let someValue = aadContext.TransactionLogs.Any(t => t.ControlNumber == ord.OrderNumber && t.TransactionType == "670"))
select new Order
{
OrderId = ord.OrderId,
WarehouseId = ord.WarehouseId,
OrderNumber = ord.OrderNumber,
CustomerPoNumber = ord.CustomerPoNumber,
ShipToCode = ord.ShipToCode,
ShipToName = ord.ShipToName,
OrderDate = ord.OrderDate,
PromisedDate = ord.PromisedDate,
DoYourValue = SomeValue
ord.Status,
ord.CustomerName,
}

Inserting Scope identity into second table using Entity Framework and dynamic Json

I have two tables as follows
1) Customers
customerId Int (primary key)
customerName Varchar(50)
Age Int
2) CustomerLoan
Id Int
customerId Int (Foreign key)
customerName Varchar(50)
Age Int
Loan float
From my jquery I am getting multiple records in the form of dynamic json object in the webservice webmethod as shown below (InsertData).
By using IList and Entity framework I am inserting multiple records.
My requirement here is while inserting customers record, I want to inert few fields from customer table and extra fields in customerloan table.
Bottom line I want to insert cutomerId generated from customer table with few more fields in CustomerLoan table.
Ex:Customer
customerId customerName Age
100 John 32
101 Jacob 35
Ex: CustomerLoan
Id customerId customerName Age Loan
1 100 John 32 1500
2 101 Jacob 35 2000
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public dynamic InsertData(int revision, int appID, dynamic jsonMaster)
{
dynamic json = jsonMaster;
IList<Customer> customers = ((object[])json).Select(t => new Customer
{
customerId = Convert.ToInt32((((IDictionary)t)["customerId"]) ?? -1),
customerName = ((((IDictionary)t)["customerName"]) ?? "").ToString(),
Age = Convert.ToInt32(((IDictionary)t)["Age"]),
Revision = Convert.ToInt32((((IDictionary)t)["Revision"])),
}).ToList(); ;
lock (_updatePointsLock)
{
using (CustomerEntities context = new CustomerEntities())
{
int currentRevision = context.Customer.Max(x => x.Revision) ?? 0;
if (currentRevision >= revision)
{
foreach (Customer cobj in customers)
{
Customer obj = context.Customer.Where(x => x.customerId == cobj.salesMasterId).FirstOrDefault();
if (obj == null)
{
cobj.Revision = currentRevision + 1;
context.Customer.Add(cobj);
**CustomerLoan objLoan = new CustomerLoan();
objLoan.customerId = cobj.customerId;
objLoan.customerName = cobj.customerName;
objLoan.Age = cobj.Age;
objLoan.customerLoan = 1500;
context.CustomerLoan.Add(objLoan);**
}
else
{
obj.customerName = cobj.customerName;
obj.Age = cobj.Age;
obj.Revision = currentRevision + 1;
}
}
context.SaveChanges();
return new
{
Revision = currentRevision + 1,
Customer = context.Customer.Where(x => x.Revision > revision).Select(x => new
{
x.customerId,
x.customerName,
x.Age,
Revision = x.Revision,
}).ToList()
};
}
else
{
return new { Revision = revision };
}
}
}
}
With the above code (-1) value inserting in customerId field in customerLoan table.
If create objects to insert outside the foreach values of Customers not getting.
If someone can help inserting identity value customer table in customerLoan highly appreciated.
First save your customer object to database with context.SaveChanges();
Then try to add Customer loan (now you should be able to find the customer Id) and save again to database with context.SaveChanges();
It may have other ways to do it but this is the way I know.

Comparing tables in the controller

I have 2 tables, one is Orders, that holds the address/list of products, and a returnDetails table. This is used when a user wants to return an Order. The returnDetails has the OrderId that is being returned.
How do I display a message only on the orders that have a return with the same OrderID? Currently only "processing" is displayed.
I used a view model to display the Orders with products.
Here is what I tried but I haven't got it working yet:
[Authorize]
public ActionResult Index(string date)
{
string currentUser = this.User.Identity.GetUserName();
List<T_shirt_Company_v3.ViewModels.MyOrdersViewModel> list = (from o in new TshirtStoreDB().Orders
.Where(o => o.Username == currentUser)
.OrderByDescending(o => o.OrderDate)
.Select(o => new MyOrdersViewModel()
{
OrderId = o.OrderId,
Address = o.Address,
FirstName = o.FirstName,
LastName = o.LastName,
City = o.City,
OrderDate = o.OrderDate,
PostalCode = o.PostalCode,
Total = o.Total,
HasBeenShipped = o.HasBeenShipped,
PostageList = o.PostageList,
Details = (from d in o.OrderDetails
select new MyOrderDetails
{
Colour = d.Product.Colour,
Quantity = d.Quantity,
Title = d.Product.Title,
UnitPrice = d.UnitPrice
}).ToList()
}).ToList() select o).ToList();
if (date != null)
{
DateTime today = DateTime.Now.AddDays(Convert.ToInt32(date) * -1);
return View(list.Where(x => x.OrderDate >= today).ToList());
}
//WORKING ON
var returnstats = db.Orders.Where(x => x.OrderId == x.returnDetails.OrderId).ToList();
if (returnstats != null)
{
ViewBag.returnstats = "Returning Item";
}
else
{
ViewBag.returnstats = "processing";
}
return View(list);
}
I think the problem is that you are not clear about what is the business logic for 'returnstats'. From the values of this variable you provide, it looks like it's for a SINGLE order instead of an order list. Here is a modified Index method for your reference:
[Authorize]
public ActionResult Index(Int32? days)
{
string currentUser = this.User.Identity.GetUserName();
var orders = db.Orders //assume db is something inherited from DbContext
.Where(o => o.UserName == currentUser)
.OrderByDescending(o => o.OrderDate);
if (days.HasValue)
{
var startingDate = DateTime.Now.AddDays((-1) * days.Value);
orders = orders.Where(o => o.OrderDate >= startingDate);
}
var orderList = orders.ToList();
var returnOrderIds = db.ReturnDetails.Select(detail => detail.OrderId).ToList();
//here you will need to check with business analyst staff what is the rule for 'returnstats'.
//The business logic here is that if there is at least one order whose OrderId is in the ReturnDetails
//the 'returnstats' is 'Returning Item' otherwise it's 'Processing'.
if (orderList.Any(o => returnOrderIds.Contains(o.OrderId))
{
ViewBag.returnstats = "Returning Item";
} else
{
ViewBag.returnstats = "processing";
}
var viewModels = ...//the source code to create Order ViewModel with variable orderList
return View(viewModels);
}

DBSet how to multiple update?

I am facing a problem when try to update records via using dbset.
The following is my code:
CROPContext db = new CROPContext();
var EPins = from EPin in db.Pins.Take(5)
where
(EPin.UserID == null && EPin.CC == 5000)
select EPin;
foreach (var item in Epins.ToList())
{
item.OrderID = OrderID;
item.UserID = intUserID;
}
db.SaveChanges();
When I update the records, it update all records.
Then I check the number EPins.Count(), I find out that it is not 5 but the number of all.
If I want to update the first 5 records, what should I do?
var EPins = (from EPin in db.Pins
where
(EPin.UserID == null && EPin.CC == 5000)
select EPin).Take(5);
foreach (var item in Epins.ToList())
{
item.OrderID = OrderID;
item.UserID = intUserID;
}
db.SaveChanges();
Try the above
db.Pins.Where(EPin => EPin.UserID == null && EPin.CC == 5000).Take(5).ToList()
.ForEach( item => { item.OrderID = OrderID; item.UserID = intUserID; });
db.SaveChanges();
If you using EF6 then you can use EntityFramework.Extended:
db.Pins.Where(EPin => EPin.UserID == null && EPin.CC == 5000)
.Update(p => new Pin { OrderID = OrderID; UserID = intUserID; });
Avoid using .ForEach because of performance implications, stream the data rather than materialise it

The entity or complex type cannot be constructed in a LINQ to Entities query

On our online billing application, we give a billing summary of what bills the customer received and the payments they made.
In order for this to work, I have to first pull the payments then match them to the bills. So I have do something like:
foreach (BillPaymentSummary payment in billPayments)
{
DateTime dt = payment.DueDate;
// Debug errors on this next line
var summary = (from a in db.BillHistories
where a.CustomerId == customerNumber && a.DueDate == dt && a.Type == "BILL"
select new BillSummary
{
Id = a.Id,
CustomerId = a.CustomerId,
DueDate = a.DueDate,
PreviousBalance = a.PreviousBalance.Value,
TotalBill = a.TotalBill.Value,
Type = a.Type,
IsFinalBill = a.IsFinalBill
}).SingleOrDefault();
if (summary != null)
{
summary.PayDate = payment.PaidDate;
summary.AmountPaid = payment.AmountPaid;
returnSummaries.Add(summary);
}
else
{
summary = (from a in db.BillHistories
where a.CustomerId == customerNumber && a.DueDate == payment.DueDate && a.Type == "ADJ "
select new BillSummary
{
Id = a.Id,
CustomerId = a.CustomerId,
DueDate = a.DueDate,
PreviousBalance = a.PreviousBalance.Value,
TotalBill = a.TotalBill.Value,
Type = a.Type,
IsFinalBill = a.IsFinalBill
}).SingleOrDefault();
if (summary != null)
{
summary.PayDate = payment.PaidDate;
summary.AmountPaid = payment.AmountPaid;
returnSummaries.Add(summary);
}
}
}
I have been playing with this, but no matter what I do, I get the following error message:
The entity or complex type 'UtilityBill.Domain.Concrete.BillSummary' cannot be constructed in a LINQ to Entities query.
Is it because I am running queries within queries? How can I get around this error?
I have tried searching Google for an answer and see many answers, but none of them seem to explain my problem.
You cannot project onto a mapped entity. You would have to call ToList() before doing your mapping.
Or better yet, change to the following (calling FirstOrDefault will execute the query and allow you to populate your object):
var summary = db.BillHistories.FirstOrDefault(a => a.CustomerId == customerNumber && a.DueDate == dt && a.Type == "BILL").Select(x => new BillSummary
{
Id = a.Id,
CustomerId = a.CustomerId,
DueDate = a.DueDate,
PreviousBalance = a.PreviousBalance.Value,
TotalBill = a.TotalBill.Value,
Type = a.Type,
IsFinalBill = a.IsFinalBill
});
To decouple yourself from the Entity Framework you may want to also consider using a different model class to return instead of the Entity Framework model.
What I ended up doing was:
foreach (BillPaymentSummary payment in billPayments)
{
var data = db.BillHistories.Where(b => b.CustomerId == customerNumber && b.DueDate == payment.DueDate && b.Type == "B").FirstOrDefault();
if (data != null) // There is a bill history
{
returnSummaries.Add(new BillSummary
{
Id = data.Id,
CustomerId = data.CustomerId,
DueDate = data.DueDate,
PreviousBalance = data.PreviousBalance,
TotalBill = data.TotalBill,
Type = (data.Type.Trim() == "B" ? "BILL" : (data.Type == "A" ? "ADJ" : "")),
IsFinalBill = data.IsFinalBill,
PayDate = payment.PaidDate,
AmountPaid = payment.AmountPaid
});
}
else // No bill history record, look for an adjustment
{
data = db.BillHistories.FirstOrDefault(b => b.CustomerId == customerNumber && b.DueDate == payment.DueDate && b.Type == "A");
if (data != null)
{
returnSummaries.Add(new BillSummary
{
Id = data.Id,
CustomerId = data.CustomerId,
DueDate = data.DueDate,
PreviousBalance = data.PreviousBalance,
TotalBill = data.TotalBill,
Type = (data.Type.Trim() == "B" ? "BILL" : (data.Type == "A" ? "ADJ" : "")),
IsFinalBill = data.IsFinalBill,
PayDate = payment.PaidDate,
AmountPaid = payment.AmountPaid
});
}
}
db.SaveChanges();
}

Categories