Can anyone explain why I'm sometimes gets a NULL exception on this insert method?
As said is only sometimes, which for me is just even more confusing.
The table OrderLine has a referemce to the table Product in the datacontext (.dbml file)
public void insertNewOrder(string accountNumber, int orderId)
{
var order = orderRep.GetOrderById(orderId);
var orderlineData = orderLineRep.GetOrderLines(order.OrderID);
foreach (var orderLine in orderlineData)
{
int currentStatus = dlvRep.getAxOrderStatusNumber(orderLine.ItemNumber, 0);
string levering = "";
string status = dlvRep.getAxOrderStatus(orderLine.ItemNumber, currentStatus, out levering);
WebsiteOrderStatus insertNew = new WebsiteOrderStatus
{
AccountNumber = accountNumber,
OrderID = orderId,
ItemNumber = orderLine.ItemNumber,
ItemName = orderLine.Product.Name,
FormatName = orderLine.Product.ProductFormatName,
Quantity = orderLine.Quantity,
Price = orderLine.Price,
Status = status,
Levering = levering,
LastUpdatedStatus = currentStatus,
CreatedDate = DateTime.Now
};
db.WebsiteOrderStatus.InsertOnSubmit(insertNew);
db.SubmitChanges();
}
}
Exception message:
Cannot insert the value NULL into column 'FormatName', table 'GWportal.dbo.WebsiteOrderStatus'; column does not allow nulls. INSERT fails.
The statement has been terminated.
When I look up the products which this code is having trouble finding the ProductFormatName for. The value of ProductFormatName is not NULL and it's having the value as I expected ex: "PS3".
Another strange thing is, why aren't it complaining about:
ItemName = orderLine.Product.Name,
This coulmn does not allow nulls either.
It's probably a bug in the code fororderLineRep.GetOrderLines(order.OrderID) that causes orderLine.Product.ProductFormatName to be set to null.
Try adding some debug code:
foreach (var orderLine in orderlineData)
{
if (orderLine.Product.ProductFormatName == null) {
throw new Exception("ProductFormatName == null");
}
// ...
Another strange thing is, why aren't it complaining about:
ItemName = orderLine.Product.Name,
This coulmn does not allow nulls either.
I can think of two explanations:
orderLine.Product.Name isn't null. The bug mentioned above may affect only ProductFormatName.
orderLine.Product.Name is null, but one error is enough to terminate the statement immediately. Only one error will be reported. Other errors that are also present won't be reported until the first error is fixed.
Related
I've seen a lot of posts about this particular error message but none seem to cover my problem. The error is :'The INSERT statement conflicted with the FOREIGN KEY constraint'
I have set a foreign key in the table called Tests as Null as not every record will have a corresponding record in the other table called APIS.
In SSMS I can insert a new record without any issue below is my INSERT query for doing so.
INSERT INTO [dbo].[Tests]
([APIID]
,[ActiveID]
,[ABCDataID]
,[ReferenceNumber]
,[LocationAddress]
,[LocationPostCode]
,[Make]
,[Model]
,[Registration]
,[WPC]
,[IsA]
,[IsS]
,[SelfSetDate]
,[IsBA]
,[UserID]
,[ClaimAtFaultEnum]
,[ClaimADriverEnum]
,[XRepair]
,[ManRepair]
,[HybridRepair]
,[BodyType]
,[CustomerName]
,[CustomerEmail]
,[CustomerMobileNumber]
,[IsCancelled]
,[CancellationNote])
VALUES
(NULL,
NULL,
NUll,
'111111111',
'Waterside',
'KA18 8EX',
'Abarth',
'320',
'TIL1607',
NULL,
1,
0,
NULL,
0,
NUll,
1,
1,
0,
0,
0,
'Car',
'John Smith',
'John#TIL1607TestData.com',
'07test',
0,
Null)
GO
Below is the same data I'm trying to put into the database using c#, it only seems to work when I set a foreign key. I can't put NULL as it's an int field and won't accept it and if I leave it out completely it comes up with the error message mentioned above.
Test testToAllocate = new Test();
if (testToAllocate != null)
{
int intClaimDriver = -1;
int intClaimAtFault = -1;
if (rdoDriverDriver.Checked)
{
intClaimDriver = (int)Enums.Test.Driver;
}
if (rdoNonDriver.Checked)
{
intClaimDriver = (int)Enums.Test.NonDriver;
}
if (rdoFaultFault.Checked)
{
intClaimAtFault = (int)Enums.Test.Fault;
}
if (rdoFaultNonFault.Checked)
{
intClaimAtFault = (int)Enums.Test.NonFault;
}
if (rdoFaultThirdParty.Checked)
{
intClaimAtFault = (int)Enums.Test.ThirdParty;
}
ABCData testToABC = db.AudaBridgeClaimDatas.Where(a => a.Registration == txtVehicleRegistration.Text).FirstOrDefault();
if (testToAllocate != null)
{
testToAllocate.ABCDataID = testToABC.ABCDataID;
}
else
{
testToAllocate.ABCDataID = null;
}
// testToAllocate.APIID = 5; //Needs to be Null
testToAllocate.ReferenceNumber = "111111111";
testToAllocate.LocationAddress = "Waterside";
testToAllocate.LocationPostCode = "KA18 8EX";
testToAllocate.Make = "Abarth";
testToAllocate.Model = "320";
testToAllocate.Registration = "TIL1607";
testToAllocate.IsA = true;
testToAllocate.IsS = false;
testToAllocate.IsBA = false;
testToAllocate.ClaimADriverEnum = 1;
testToAllocate.ClaimAtFaultEnum = 1;
testToAllocate.XRepair = false;
testToAllocate.ManRepair = false;
testToAllocate.HybridRepair = false;
testToAllocate.BodyType = "Car";
testToAllocate.CustomerName = "John Smith";
testToAllocate.CustomerEmail = "John#TIL1607TestData.com";
testToAllocate.CustomerMobileNumber = "07test";
testToAllocate.IsCancelled = false;
db.Claims.InsertOnSubmit(testToAllocate);
db.SubmitChanges();
Anyone got any ideas? It's almost as if visual studio hasn't recognized the change I made to the database to make this field null.
I can't put NULL as it's an int field and won't accept it
Then your model doesn't reflect your database. If your database has a nullable field, you need a nullable int: int?
if I leave it out completely it comes up with the error message mentioned above
Because the model has the wrong data type for that field, and the default value for int is 0. If there's no corresponding record 0 in the target table, that's a foreign key constraint violation.
It's almost as if visual studio hasn't recognized the change I made to the database to make this field null.
Indeed. If you're using some tool to generate your classes from the database, re-run that tool. If not, update your model accordingly. You have a nullable database field and a non-nullable model field.
Basically, where on your model you have something like this:
public int SomeField { get; set; }
What you want is something like this:
publit int? SomeField { get; set; }
Then you can set SomeField to null.
I have set a foreign key in the table called Tests as Null
I can't put NULL as it's an int field and won't accept it
Instead of int, make the type int? ,which is a nullable int. This will allow you set the value to null.
See MSDN
I have the following method to save order properties on a purchase order:
public void SetOrderProperty(string orderPropertyName, string value)
{
PurchaseOrder purchaseOrder = TransactionLibrary.GetBasket().PurchaseOrder;
OrderProperty orderProperty = purchaseOrder.OrderProperties.FirstOrDefault(x => x.Key == orderPropertyName);
if (orderProperty != null)
{
orderProperty.Value = value;
orderProperty.Save();
}
else
{
OrderProperty op = new OrderProperty
{
Key = orderPropertyName,
Value = value,
Order = purchaseOrder
};
op.Save();
}
purchaseOrder.Save();
TransactionLibrary.ExecuteBasketPipeline();
}
When I save a value using this I can see it appear against the order in the uCommerce_OrderProperty table.
However, with some properties, when I try to read them back out they are missing:
public string GetOrderProperty(string orderPropertyName)
{
PurchaseOrder purchaseOrder;
using (new CacheDisabler())
{
purchaseOrder = TransactionLibrary.GetBasket().PurchaseOrder;
}
OrderProperty orderProperty = purchaseOrder.OrderProperties.FirstOrDefault(x => x.Key == orderPropertyName);
if (orderProperty != null)
{
return orderProperty.Value;
}
return string.Empty;
}
I have also tried this code from the uCommerce site:
public string GetOrderProperty(string orderPropertyName)
{
PurchaseOrder purchaseOrder = SiteContext.Current.OrderContext.GetBasket().PurchaseOrder;
return purchaseOrder[orderPropertyName];
}
If I inspect purchaseOrder I can see the OrderProperties are missing. I have 7 properties at any one time but purchaseOrder only ever seems to have a max of 5 even though there is 7 in the table.
These are Order Properties and not Order Line Properties. Can anyone give me any pointers as to why I am seeing this behaviour?
EDIT
This line does get the value I am looking for:
OrderProperty op = OrderProperty.FirstOrDefault(x => x.Order.OrderId == purchaseOrder.OrderId && x.Key == orderPropertyName);
Even when this line (called the line after) returns null:
OrderProperty orderProperty = purchaseOrder.OrderProperties.FirstOrDefault(x => x.Key == orderPropertyName);
(Both are looking for the same Order Property)
Can anyone tell me why?
I have a comment, but I'm not allowed because of missing reputation.
Everything seems to be fine regarding your code. Can I persuade you to show the
uCommerce_OrderProperty table?
- I just want to check that the OrderLineId column is empty for you order properties.
You should be able to set and get it like this:
var property = order[orderPropertyName];
order[orderPropertyName] = "VALUE";
Regards
Mads
We also recommend that Ucommerce related question is posted at http://eureka.ucommerce.net/, the response time is often faster.
I'm getting this error when i run my server:
An exception of type
'System.Data.Entity.Core.EntityCommandExecutionException' occurred in
EntityFramework.SqlServer.dll but was not handled in user code
Additional information: An error occurred while executing the command definition. See the inner exception for details.
Here's my ActionResult where this exception occurs, at line in foreach loop. Table bid from database has foreign key constraint to AspNetUser table.
public ActionResult Details(long? id)
{
if (id == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
auction auction = db.auctions.Find(id);
if (User.IsInRole("Administrator"))
ViewBag.UserRole = "Administrator";
else if (User.IsInRole("User"))
ViewBag.UserRole = "User";
else
ViewBag.UserRole = "Guest";
var bids = from b in db.bids
where b.IDAuc == id
orderby b.tokens
descending select b;
var bidsLimited = bids.Take(10);
var users = from b in db.AspNetUsers
select b;
int count = bidsLimited.Count();
long[] prices = new long[count];
string[] bidders = new string[count];
string[] times = new string[count];
string[] states = new string[count];
int i = 0;
foreach (var bid in bidsLimited)
{
prices[i] = bid.tokens;
bidders[i] = bid.AspNetUser.Email; // HERE IS EXCEPTION
times[i] = bid.created.ToString(#"dd\:hh\:mm\:ss");
states[i++] = "Open";
}
if (auction.state == "Sold")
states[0] = "Sold";
ViewBag.count = count;
ViewBag.prices = prices;
ViewBag.bidders = bidders;
ViewBag.times = times;
ViewBag.states = states;
ViewBag.IDAuction = id;
return View(auction);
}
Here's detailed error:
I'm really confused, first time seeing this exception, hope someone will help me solve this out.
Thanks in advance!
Is it possible one of the records in the bid variable doesn't have an AspNetUser ID value specified, so the relationship is null? Another workaround is I do sometimes have strange errors like this, where even though the ID is specified, the error still persists. Since you've loaded up all of the related user data into the users variable, you could change the line from:
bidders[i] = bid.AspNetUser.Email; // HERE IS EXCEPTION
To
bidders[i] = users.First(i => i.AspNetUserID == bid.AspNetUserID).Email;
i.AspNetUserID is the AspNetUser's ID field (I don't know what it's called, so replace i.AspNetUserID with the correct value) to the bid table's AspNetUserID field (again, replace with the correct name).
If that fails, the user found is NULL, there is a problem somewhere that needs to be determined; the user isn't linked and coming back, and for that you need to identify the specific record in the bid variable that isn't linked properly...
I am currently developing a MS Dynamics CRM 2013 - Plugin.
When I try to assign a string-value to a key of a field of an entity it gives me the 'keynotfound'-exception.
This leaves me clueless, because I can verify the key is existing. The key I give is also written correctly, and the data types are compatible, too.
Here's some extra info:
I tried resolving the issue with a server reboot. Nothing.
Remote Debugging is not an option.
I swapped "retrieved.EntityCollection.Entities[i][forField]" with retrieved.EntityCollection.Entities[i]["new_name"] and everything was working fine (kind of pointing out the obvious here, but "new_name" is not the key I try to access).
The execution stops # "if (retrieved.EntityCollection.Entities[i][forField].ToString() != "" && !overwriteExisting)"
Have you got an idea to help me out?
public void GenerateNumberForEntityCollection(string target)
{
try
{
// variables for number generation
bool overwriteExisting = (bool)preImageEntity["new_overwriteexisting"];
int suffixstart = (int)preImageEntity["new_suffixstart"];
string forField= preImageEntity["new_forfield"].ToString();
string prefix = preImageEntity["new_prefix"].ToString();
string postfix = preImageEntity["new_postfix"].ToString();
string separator = preImageEntity["new_separator"].ToString();
// Build query to get all the entries
RetrieveMultipleResponse retrieved;
int PageNumber = 1;
string PagingCookie = string.Empty;
int PageSize = 5000;
string[] Columns = { forField };
QueryExpression query = new QueryExpression()
{
EntityName = target,
ColumnSet = new ColumnSet(Columns),
PageInfo = new PagingInfo()
{
PageNumber = 1,
Count = PageSize
}
};
do
{
if (PageNumber != 1)
{
query.PageInfo.PageNumber = PageNumber;
query.PageInfo.PagingCookie = PagingCookie;
}
RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
retrieve.Query = query;
retrieved = (RetrieveMultipleResponse)service.Execute(retrieve);
// Now that all entities are retrieved, iterate through them to gen. the numbers
int i = 0;
foreach (Entity entity in retrieved.EntityCollection.Entities)
{
if (retrieved.EntityCollection.Entities[i][forField].ToString() != "" && !overwriteExisting)
{
//continue;
}
else
{
retrieved.EntityCollection.Entities[i][forField] = prefix + separator + suffixstart.ToString() + separator + postfix;
}
suffixstart++;
service.Update(retrieved.EntityCollection.Entities[i]);
i++;
}
if (retrieved.EntityCollection.MoreRecords)
{
PageNumber++;
PagingCookie = retrieved.EntityCollection.PagingCookie;
}
} while (retrieved.EntityCollection.MoreRecords);
}
catch (Exception e)
{
tracing.Trace("GenerateNumberForEntityCollection: Failed: {0}", e.ToString());
}
}
How did you verify that the key exists?
If the data in a field is null, the Entity instance will not contain that key, even if you specify it in the query's ColumnSet.
This will return you a boolean, indicating if the key exists in the Entity. You can do this control before attempting to read the attribute.
var attributeExists = retrieved.EntityCollection.Entities[i].Contains(forField)
The control below you've done will result in the exception you're getting if the field is null. Just make sure that the attribute exists before.
retrieved.EntityCollection.Entities[i][forField].ToString() != ""
Additionally, you'll get a null reference exception if no records were returned from the query. Make you do a null check on retrieved.EntityCollection.Entities.
When you are querying data in Dynamics CRM it is important to know that record fields having null values in the database are not included in the Attributes collection of the Entity instances being returned.
Getting a value from an Entity's Attribute with this construct:
var value = retrieved.EntityCollection.Entities[i][forField].ToString();
succeeds when attribute forField already has a value in the database, but fails when its current value is null.
Therefore the preferred method to get the attribute values from an entity is GetAttributeValue<T>, like this:
var value = retrieved.EntityCollection.Entities[i].getAttributeValue<string>(forField);
This method returns the value when the attribute exists in the attribute collection, otherwise it returns null.
If any of the fields among
(new_forfield,new_prefix,new_postfix,new_separator) has null value,
that column does not present in the retrieved object and you are trying to get the value of null column preImageEntity["new_forfield"] which will throw keynotfound'-exception ,
so change the code
string forField= preImageEntity["new_forfield"].ToString();
string prefix = preImageEntity["new_prefix"].ToString();
string postfix = preImageEntity["new_postfix"].ToString();
string separator = preImageEntity["new_separator"].ToString();
to
string forField = preImageEntity.Attributes.Contains("new_forfield")? preImageEntity["new_forfield"].ToString():"";
string prefix = preImageEntity.Attributes.Contains("new_forfield") ? preImageEntity["new_prefix"].ToString() : "";
string postfix = preImageEntity.Attributes.Contains("new_forfield") ? preImageEntity["new_postfix"].ToString() : "";
string separator = preImageEntity.Attributes.Contains("new_forfield") ? preImageEntity["new_separator"].ToString() : "";
this will check for field, if it exists than will parse the value to
string else will assign empty string.
My Db column in a string (varchar) and i need to assign it to a int value.
I am using linq to query.Though the code compiles am getting an error at the run time .
Thanks in advance.
PFB my query :
var vlauesCap = from plan in entities.PA_RTM_CAP_Group
select new Business.PartnerProfile.LookUp
{
Id =Convert.ToInt32(plan.cap_group_code),
//(Int32)plan.cap_group_code,
Value = plan.cap_group_name
};
return vlauesCap.ToList();
The EF provider does not know how to translate Convert.ToInt() into SQL it can run against the database. Instead of doing the conversion on the server, you can pull the results back and do the conversion using linq to objects:
// the ToList() here causes the query to be executed on the server and
// the results are returned in a list of anonymous objects
var results = (from plan in entities.PA_RTM_CAP_Group
select new
{
Code = plan.cap_group_code,
Name = plan.cap_group_name
}).ToList();
// the conversion can now be done here using Linq to Objects
var vlauesCap = from r in results
select new Business.PartnerProfile.LookUp
{
Id = Convert.ToInt32(r.Code),
Value = r.Name
};
return vlauesCap.ToList();
You can't do this directly, what you can do is declare a private variable to handle your "mapped" value, and expose the unmapped property...
[Column(Name = "cap_group_code", Storage = "m_cap_group_code")]
private string m_cap_group_code;
public int cap_group_code {
get
{
return Int32.Parse(m_cap_group_code);
}
set
{
m_cap_group_code = value.ToString();
}
}
Try this:
var vlauesCap = from plan in entities.PA_RTM_CAP_Group
select new Business.PartnerProfile.LookUp
{
Id =Convert.ToInt32(plan.cap_group_code),
Convert.ToInt32(plan.cap_group_code),
Value = plan.cap_group_name
};
return vlauesCap.ToList();
Why aren't you using casting for such a purpose, which is a more effective way of achieving this.
Just replace Convert.ToInt32(plan.cap_group_code) with (int)plan.cap_group_code
Do remember, there should be a value in the string and is int, else it will show Exception. If you are not sure about it, then you can further expand the casting to use null coalesciting operator