View Criteria not returning row - criteria

I'm new to ADF BC and I'm trying to save a record in the DB.
If the record already exists, I'll update the fields if not I'll create a new row.
I'm using the same View Criteria in other methods and it works, but not in this method. Here's my code:
public String saveRecord() {
boolean isNewRow = false;
String merchId = generateIds(); //returns the correct Id, I've checked
DCIteratorBinding dc = (DCIteratorBinding)evaluteEL("#{bindings.GaeInitialSetup1Iterator}");
ViewObject vo = dc.getViewObject();
ViewCriteriaManager vcm = vo.getViewCriteriaManager();
vo.setNamedWhereClauseParam("merchId", merchId);
vcm.applyViewCriteria(vo.getViewCriteriaManager().getViewCriteria("GaeInitialSetupVOCriteria"));
vo.executeQuery();
Row rowSelected = vo.next(); //it's always null even if the record exists
if (rowSelected == null) { // null == null - leads to error when trying to insert the same Id twice
isNewRow = true;
rowSelected = vo.createRow();
rowSelected.setAttribute("MerchId", merchId);
rowSelected.setAttribute("MerchLevel", merchLevelCalc(merchId));
rowSelected.setAttribute("ParentId", parentIdCalc(merchId));
}
rowSelected.setAttribute("IpssDefault", validateIPSSDefault());
rowSelected.setAttribute("IpssBase", validateIPSSBase());
rowSelected.setAttribute("LimMinMdqPct", validateLIM_MIN_MDQ_PCT());
rowSelected.setAttribute("LimMinMdqPctNewSku", validateLIM_MIN_MDQ_PCT_NEW_SKU());
rowSelected.setAttribute("DifMdqPctMin", validateDIF_MDQ_PCT_MIN());
rowSelected.setAttribute("VarMinMdqChg", validateVAR_MIN_MDQ_CHG());
rowSelected.setAttribute("LimMinRotDays", validateLIM_MIN_ROT_DAYS());
rowSelected.setAttribute("LimMaxRotDays", validateLIM_MAX_ROT_DAYS());
rowSelected.setAttribute("DaysNewSku", validateDAYS_NEW_SKU());
rowSelected.setAttribute("IncrS1", validateINCR_S1());
rowSelected.setAttribute("IncrS2", validateINCR_S2());
rowSelected.setAttribute("IncrS3", validateINCR_S3());
rowSelected.setAttribute("IncrS4", validateINCR_S4());
rowSelected.setAttribute("ReplSuspComb", validateREPL_SUSP_COMB());
rowSelected.setAttribute("VarPctMinStkRot", validateVAR_PCT_MIN_STK_ROT());
rowSelected.setAttribute("AbcgA", validateABCG_A());
rowSelected.setAttribute("AbcgB", validateABCG_B());
rowSelected.setAttribute("AbcgC", validateABCG_C());
rowSelected.setAttribute("AbcgD", validateABCG_D());
rowSelected.setAttribute("AbcgE", validateABCG_E());
rowSelected.setAttribute("AbcgF", validateABCG_F());
rowSelected.setAttribute("AbcgG", validateABCG_G());
if (isNewRow) {
vo.insertRow(rowSelected);
}
DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
OperationBinding operationBinding = (OperationBinding)bindings.getOperationBinding("Execute");
operationBinding.execute();
OperationBinding operationBinding2 = (OperationBinding)bindings.getOperationBinding("Commit");
operationBinding2.execute();
return null;
}
What am I missing?

Your code seems perfectly right, could you try making the below mentioned changes?
vo.executeQuery();
if (vo.hasNext()) {
Row rowSelected = vo.next();
//write rest of your logic here
}
This will not have null == null check and is the best practice.

I've fixed the problem.
I removed the line: Row rowSelected = vo.next();
And I've added: Row rowSelected = vo.first();

Related

How do I populate a LiteDB database if some of my values are null

I am populating a dataGridView from an incomplete excel spreadsheet and generating the LiteDB from the dataGridView. Before the recent update, I wasn't having any issues. Now I am getting the error 'Objects cannot be cast from DBNull to other types'. I can work around this by including dummy values in the original spreadsheet. But ultimately we need to see what information we're missing. How can I accomplish this?
public void CreateDatabase()
{
using (var db = new LiteDatabase(#"C:\Users\BThatcher\Documents\_Personal\Revit\MDL-Sheets\SheetDatabase04.db")) //< ----------------
{
var sheets = db.GetCollection<Sheet>("sheets");
foreach (DataGridViewRow row in dataGridView2.Rows)
{
var sheet = new Sheet
{
SheetSequence = Convert.ToInt32(row.Cells[0].Value),
SheetNumber = row.Cells[1].Value.ToString(),
SheetName = row.Cells[2].Value.ToString(),
AreaNumber = Convert.ToInt32(row.Cells[3].Value),
AreaName = row.Cells[4].Value.ToString(),
SheetDiscipline = row.Cells[5].Value.ToString(),
DisciplineSort = Convert.ToInt32(row.Cells[6].Value),
SheetSort = Convert.ToInt32(row.Cells[7].Value),
ModelName = row.Cells[8].Value.ToString(),
AppearsInSheetlist = row.Cells[9].Value.ToString(),
DesignedBy = row.Cells[10].Value.ToString(),
DrawnBy = row.Cells[11].Value.ToString(),
CheckedBy = row.Cells[12].Value.ToString(),
ApprovedBy = row.Cells[13].Value.ToString(),
SheetTotal = Convert.ToInt32(row.Cells[14].Value),
DesignSoftware = row.Cells[15].Value.ToString(),
HasPdf = row.Cells[16].Value.ToString(),
PdfPath = row.Cells[17].Value.ToString(),
};
sheets.Insert(sheet);
this.Close();
}
}
}
This error are not from LiteDB (there is no DBNull in LiteDB). It's possible this DBNull are getting from row.Cells[n].Value when you try to convert.
LiteDB support nulls and nullable values (like int?).

EF6 update not actually updating the table record?

I'm having to write a app that effectively copies data from one databaseA.table to databaseB.table but there are a few fields in databaseB that aren't in databaseA.
I've come up with basic code below. The insert works and the update doesn't trow an error, however, the update doesn't actually update any records.
I've confirmed that the bcEmployee object in the update has the new values from databaseA like it should. The employee object is the record from databaseA.
Am I missing something to make this update?
BC_employee bcEmployee = new BC_employee();
bcEmployee.emp_id = employee.emp_id;
bcEmployee.emp_firstname = employee.emp_firstname;
bcEmployee.emp_lastname = employee.emp_lastname;
using (BCcontext ctx = new BCcontext())
{
var existBCemployee = ctx.employee.Find(employee.emp_id);
if (existBCemployee == null) //Insert
{
//Set default values that aren't in the original database
bcEmployee.emp_paystat = null;
bcEmployee.password = null;
bcEmployee.enroll_date = null;
ctx.employee.Add(bcEmployee);
}
else
{
ctx.Entry(existBCemployee).CurrentValues.SetValues(bcEmployee);
}
ctx.SaveChanges();
}

Why does this query always return ALL records?

I'm using WCF RIA in a Lightswitch project to create some query results. This query brings back all results regardless. I cannot make it filter the records based on the parameter passed (string Town).
public IQueryable<Enquiries> TestQuery(string Town)
{
List<Enquiries> riaenqs = new List<Enquiries>();
var enqs = this.Context.ClientEnquiries
.Include("Client")
.Include("Client.Town")
.OrderBy(enq => enq.Id);
if (Town != null)
{
enqs.Where(enq => enq.Client.Town.TownName == Town);
}
foreach (ClientEnquiry item in enqs.ToList())
{
Enquiries enq = new Enquiries();
enq.Id = item.Id;
enq.ClientName = item.Client.FirstName + " " + item.Client.Surname;
enq.Town = item.Client.Town != null ? item.Client.Town.TownName : null;
riaenqs.Add(enq);
}
return riaenqs.AsQueryable();
}
During debugging I can see that the Town is correctly populated and I can see that the query is built accordingly if Town is not null. However, when I hit the foreach statement where the linq to ef query is executed I always get all the results. I just cannot figure out where I'm slipping up.
The LINQ methods like the Where do not modify the collection/expression but always returning a new one.
So you need to reassign the result of the Where to your original variable enqs:
if (Town != null)
{
enqs = enqs.Where(enq => enq.Client.Town.TownName == Town);
}

CRM 2011 : Plugin to create duplicate records

i created a simple plugin to create a duplicate record that refers to the parent record.
Here is my code
var pluginExecutionContext = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;
abc= pluginExecutionContext.InputParameters["Target"] as Entity;
if (pluginExecutionContext.Depth == 1)
{
Guid abcId = abc.Id;
Entity abcCopy = new Entity("mcg_abc");
if (abc.Attributes.Contains("mcg_abccategoryoptioncode"))
{
abcCopy.Attributes["mcg_abccategoryoptioncode"] = abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode");
}
if (abc.Attributes.Contains("mcg_effectivedate"))
{
abcCopy.Attributes["mcg_effectivedate"] = isp.GetAttributeValue<DateTime>("mcg_effectivedate");
}
if (abc.Attributes.Contains("mcg_startdate"))
{
abcCopy.Attributes["mcg_startdate"] = isp.GetAttributeValue<DateTime>("mcg_startdate");
}
if (abc.Attributes.Contains("mcg_enddate"))
{
abcCopy.Attributes["mcg_enddate"] = isp.GetAttributeValue<DateTime>("mcg_enddate");
}
if (abc.Attributes.Contains("mcg_amendeddate"))
{
abcCopy.Attributes["mcg_amendeddate"] = isp.GetAttributeValue<DateTime>("mcg_amendeddate");
}
if ((abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode").Value) == 803870001)
{
//Some more fields;
}
else
{
//Some more fields;
}
// SOme more fields;
abcCopy.Attributes["mcg_parentabc"] = new EntityReference("mcg_abc", abc.Id);
service.Create(abcCopy);
}
Now the problem is all the fields before the below check are getting copied
if ((abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode").Value) == 803870001)
However fields after this check are not getting copied.
Please if anybody could suggest what mistake i have made.
In case you take field from Target - this field was updated on a client side. In case field was not updated - it would not be in Target. You should use Images to get values of unchanged fields.
The field must be empty so a exception may arise. Try to use the plugin image or change your code to this way:
if (abc.Attributes.Contains("mcg_abccategoryoptioncode")){
if ((abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode").Value) == 803870001)
....

Entity Framework, one-to-many, several columns

If I have a main table, lets say orders, and a sub table of items and the items table has a fields for item number BUT it also has a nullable (optional) field for color that applied only to certain items. How would I update the items table, at the same time as the orders table, using Entity Framework?
Here is a code example of what I have so far. Two problems, I'm only entering one of my items and, from what my research indicates, I can't add another field to the items table?
foreach (Guid c in AllItems)
{ Items.OrderItemID = Guid.NewGuid();
ITemsOrderID = order.OrderID;
ITems.ItemID = c;
If (ItemID = ItemThatLetsYouChoseAColorID)
{
Items.ItemColorID = ColorID;
} else {
Items.ItemColorID = null;
}
}
context.Orders.AddObject(Orders);
context.Items.AddObject(Items);
context.SaveChanges();
My Orders table gets a record inserted, and the Items gets ONE record inserted. I'm missing something basic here, I'm afraid. BTW, this is Entity Framework 4.0, which. I believe, does not require the use of EntityKey.
You're adding an object to the Items collection only one time after the scope of your foreach.
Have you tested something like:
foreach (Guid c in AllItems)
{
var Item = new Item();
Item.OrderItemID = Guid.NewGuid();
Item.OrderID = order.OrderID;
Item.ItemID = c;
If (ItemID = ItemThatLetsYouChoseAColorID)
{
Item.ItemColorID = ColorID;
}
else
{
Item.ItemColorID = null;
}
context.Items.AddObject(Items);
}
context.Orders.AddObject(order);
context.SaveChanges();
And I'm not sure to understand what you mean by
I can't add another field to the items table
You should be more precise about what you actually expect. Insert a row, add a column in the table...? What is a "field"?
Here is the working code. I had the new Item outside the foreach item loop, so was overwriting the value. Also, I need to add each one to the context. I had a hard time with this, hope it helps someone else:
<-fill the order object->
foreach (Guid i in Items)
{
**Items item = new Items();**
item.ItemID = Guid.NewGuid();
item.OrderID = order.OrderID;
if (i == ItemWithColorGuid)
{
foreach (Guid c in Colors)
{
**Items color = new Items();**
color.ItemsID = Guid.NewGuid();
color.OrderID = order.orderID;
color.itemID = g;
color.colorID = c;
context.item.AddObject(color);
}
}
else
{
item.ItemID = i;
item.ColorID = null;
context.item.AddObject(item);
}
}
context.orders.AddObject(order);
context.SaveChanges();