Trying to update/insert many to many relationship via Linq to Entities - asp.net

I am trying to do a combined add/update function on a many-to-many relationship. DB first. Have three sql tables: Personnel, Orders, PersonnelOrders. Here is my code:
context.ContextOptions.LazyLoadingEnabled = true;
if (saveData.Rows.Count() > 1)
{
foreach (var row in saveData.Rows)
{
if (row != null)
{
var Order_Array = row.Order_Array; //Array of order id's to be used below.
var pData = new Personnel;
{
Personnel_Id = row.Key,
Personnel_Name = row.Name
};
if (pData.Personnel_Id == 0) //ADD
{
foreach (int Id in Order_Array)
{
pData.Orders.Add(new Order() { Order_Id = Id });
}
context.Personnel.AddObject(cvData);
foreach (var j in pData.Orders)
{
context.ObjectStateManager.ChangeObjectState(j, EntityState.Unchanged);
}
}
else //Doesn't error out, but does not work either:
{
pData.Orders.Clear();
foreach (int Id in Order_Array)
{
pData.Orders.Add(new Order() { Order_Id = Id });
}
context.Personnel.Attach(cvData);
context.ObjectStateManager.ChangeObjectState(pData, EntityState.Modified);
}
context.SaveChanges();
}
}
}
return "ok";
EDIT: I got the ADD to work, now I'm stuck on UPDATE. See revised code above.

This is what I had to do to make it work. It looks ugly to me and I'm sure it can be refined, but it works for now.
context.ContextOptions.LazyLoadingEnabled = true; //not sure that this is necessary
if (saveData.Rows.Count() > 1)
{
foreach (var row in saveData.Rows)
{
if (row != null)
{
var Order_Array = row.Order_Array;
if (row.Key == 0) //ADD
{
var pData = new Personnel;
{
Personnel_Id = row.Key, //probably not needed but it doesn't break it
Personnel_Name = row.Name
};
foreach (int Id in Order_Array)
{
var j = context.Orders.Where(c => c.Order_Id == Id).SingleOrDefault();
pData.Orders.Add(j);
}
context.Personnel.AddObject(pData);
foreach (var j in pData.Orders)
{
context.ObjectStateManager.ChangeObjectState(j, EntityState.Unchanged); //so that you don't actually add more orders
}
}
else //UPDATE
{
var ap = context.Personnel.FirstOrDefault(x => x.Personnel_Id == row.Key);
ap.Personnel_Name = row.Name;
ap.Orders.Clear(); //clear out existing associations
foreach (int Id in Order_Array)
{
var j = context.Orders.Where(c => c.Order_Id == Id).SingleOrDefault();
ap.Orders.Add(j); //rebuild new associations
}
}
context.SaveChanges();
}
}
}

Related

Asp.net Telerik script issue

I have a line of code which comes inside a Telerik.Web.UI.Webresource.axd file which breaks something in my custom code.
dataBind:function(){if(this._virtualization&&!this._virtualization._isDataBinding&&((this.get_allowPaging()&&this._dataSource.length>this.get_pageSize())||(!this.get_allowPaging()&&this._dataSource.length>this._virtualization._itemsPerView))){this._virtualization._startIndex=null;
this._virtualization.set_bindingType("Client");
this._virtualization.set_cachedData(this._dataSource);
this._virtualization.set_virtualItemCount(this._dataSource.length);
this._virtualization.select();
return;
}
**Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0],"rgGroupHeader"),function(i){i.parentNode.removeChild(i)**;
});
I would like to know if it is possible to prevent the below line of code to be executed
Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0],"rgGroupHeader"),function(i){i.parentNode.removeChild(i)**;
You can override the dataBind method of RadGrid which will allow you to customize it:
<script>
Telerik.Web.UI.GridClientSideBinding.prototype.dataBind = function () {
// Virtualization
if (this._virtualization && !this._virtualization._isDataBinding &&
((this.get_allowPaging() && this._dataSource.length > this.get_pageSize()) ||
(!this.get_allowPaging() && this._dataSource.length > this._virtualization._itemsPerView))) {
this._virtualization._startIndex = null;
this._virtualization.set_bindingType("Client");
this._virtualization.set_cachedData(this._dataSource);
this._virtualization.set_virtualItemCount(this._dataSource.length);
this._virtualization.select();
return;
}
Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0], "rgGroupHeader"), function (element) {
element.parentNode.removeChild(element);
});
Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0], "rgFooter"), function (element) {
element.parentNode.removeChild(element);
});
var noRecordsItem = $telerik.getElementByClassName(this.get_element(), "rgNoRecords");
if (noRecordsItem) {
if (this._dataSource.length > 0) {
noRecordsItem.style.display = "none";
} else {
noRecordsItem.style.display = "";
this._setPagerVisibility(this._data.PagerAlwaysVisible);
}
}
var dataItems = this.get_dataItems();
var columns = this.get_columns();
var i, l1, l2;
var tableElement = ($telerik.isOpera) ? this.get_element() : this.get_element().tBodies[0];
if (this._dataSource.length < dataItems.length || tableElement.rows.length == 1) {
for (i = 0, l1 = dataItems.length; i < l1; i++) {
dataItems[i].set_visible(false);
dataItems[i].get_element().style.display = "none";
}
this._cacheDataItems();
}
this._dataBind(this._dataSource);
var firstSelection = true;
// When YahooStyleScrolling is used in RadGrid and user
//scrolls down, select multiple rows using shift + down arrow key,
//the selection is not persisted on next page load
if (this._owner._keyboardNavigationProperties) {
firstSelection = this._owner._keyboardNavigationProperties.firstSelection;
}
var owner = $find(this._owner.get_id());
if (owner._getPositionedDataItems) {
owner._getPositionedDataItems(true);
}
if (this._owner._keyboardNavigationProperties) {
this._owner._keyboardNavigationProperties.firstSelection = firstSelection;
}
this._fixRowsClassNames();
this._owner.raise_dataBound(Sys.EventArgs.Empty);
for (i = 0, l2 = columns.length; i < l2; i++) {
var isVisible = false;
if (columns[i].get_element().style.visibility != "hidden" && (columns[i].Display == null || columns[i].Display == true) &&
(columns[i]._data.Display == null || columns[i]._data.Display)) {
isVisible = true;
}
if (!isVisible) {
this.hideColumn(i);
}
}
if (this.get_id() == this._owner._masterClientID) {
var grid = $find(this._owner.get_id());
if (grid._scrolling) {
this._owner._scrolling.setHeaderAndFooterDivsWidth();
grid._scrolling._initializeVirtualScrollPaging(true);
}
}
}
</script>

Getting Null data from google adwords api

I want to fetch location details for all the ads from google adwords but I am getting null entries.I am not able to get any data from adwords api .Help me in That as according to my knowledge there is not problem with my code and I am not able to find any solution for that.My code that I have tried is written below.
public void GetLocationAds()
{
AdWordsUser user = new AdWordsUser();
{
try
{
int offset = 0;
// Create selector.
using (CampaignCriterionService campaignCriterionService =
(CampaignCriterionService)user.GetService(AdWordsService.v201809.CampaignCriterionService))
{
Selector selector = new Selector()
{
fields = new string[]
{
CampaignCriterion.Fields.CampaignId,
CampaignCriterion.Fields.CampaignCriterionStatus,
//Location.Fields.LocationName,
//Location.Fields.CriteriaType,
//Location.Fields.ParentLocations,
//LocationCriterion.Fields.CanonicalName,
//LocationCriterion.Fields.CountryCode,
CampaignCriterion.Fields.IsNegative,
},
// predicates = new Predicate[]
//{
// Predicate.Equals( "CriteriaType","LOCATION"),
//},
paging = Paging.Default,
ordering = new OrderBy[]
{
OrderBy.Asc( CampaignCriterion.Fields.CampaignId)
}
};
CampaignCriterionPage page = new CampaignCriterionPage();
do
{
// Get the ad groups.
page = campaignCriterionService.get(selector);
// Display the results.
if (page != null && page.entries != null)
{
int j = selector.paging.startIndex;
foreach (CampaignCriterion campaignCriterion in page.entries)
{
var campaignId = campaignCriterion.campaignId;
bool IsLocation = campaignCriterion.isNegative;
var CampaignCriterionType = campaignCriterion.CampaignCriterionType;
}
}
else
{
Console.Write("No campaignCriterion were found.");
}
selector.paging.IncreaseOffset();
}
while (selector.paging.startIndex < page.totalNumEntries);
}
}
catch (Exception ex)
{
}
}
}
Kindly help me in that.

EntityFramework,Navigation properties' Changes cannot be SAVE

//Hi,the following code snippet ,I want to Change the model and it's related entities according to the model's naviagation properties,But only affected the model scale properties.There is NO Exception in runtime.I don't know WHY ,please help me,Thanks a lot!
public bool Update(Container model)
{
var mExist=dbContext.Container.SingleOrDefault(m=>m.TransportDocumentId==model.TransportDocumen tId && m.ContainerNo==model.ContainerNo);
if (mExist != null)
{
if (mExist.Id != model.Id)
{
throw new Exception("The same entity has been exist!.");
}
dbContext.Entry(mExist).State = EntityState.Detached;
}
var mOld = dbContext.Container.SingleOrDefault(m => m.Id == model.Id);
string oldContainerNo = model.ContainerNo;
if (mOld != null)
{
oldContainerNo = mOld.ContainerNo;
dbContext.Entry(mOld).State = EntityState.Detached;
}
dbContext.Container.Attach(model);
var mGoods = model.TransportDocument.Goods;
if (model.ContainerNo != oldContainerNo)
{
foreach (var g in mGoods)
{
var gn = g.GoodsContainerNo.Where(n => n.ContainerNo == oldContainerNo);
foreach (var gNo in gn)
{
//WHY,here CHANGES cannot be save to datastore!!!
gNo.ContainerNo = model.ContainerNo;
dbContext.Entry(gNo).State = EntityState.Modified;
}
}
}
dbContext.Entry(model).State = EntityState.Modified;
return dbContext.SaveChanges() >= 0;
}

In AS3/Flex, how can I get from flat data to hierarchical data?

I have some data that gets pulled out of a database and mapped to an arraycollection. This data has a field called parentid, and I would like to map the data into a new arraycollection with hierarchical information to then feed to an advanced data grid.
I think I'm basically trying to take the parent object, add a new property/field/variable of type ArrayCollection called children and then remove the child object from the original list and clone it into the children array? Any help would be greatly appreciated, and I apologize ahead of time for this code:
private function PutChildrenWithParents(accountData : ArrayCollection) : ArrayCollection{
var pos_inner:int = 0;
var pos_outer:int = 0;
while(pos_outer < accountData.length){
if (accountData[pos_outer].ParentId != null){
pos_inner = 0;
while(pos_inner < accountData.length){
if (accountData[pos_inner].Id == accountData[pos_outer].ParentId){
accountData.addItemAt(
accountData[pos_inner] + {children:new ArrayCollection(accountData[pos_outer])},
pos_inner
);
accountData.removeItemAt(pos_outer);
accountData.removeItemAt(pos_inner+1);
}
pos_inner++;
}
}
pos_outer++;
}
return accountData;
}
I had a similar problem with a hierarchical task set which was slightly different as it has many root elements, this is what i did, seems good to me:
public static function convertFlatTasks(tasks:Array):Array
{
var rootItems:Array = [];
var task:TaskData;
// hashify tasks on id and clear all pre existing children
var taskIdHash:Array = [];
for each (task in tasks){
taskIdHash[task.id] = task;
task.children = [];
task.originalChildren = [];
}
// loop through all tasks and push items into their parent
for each (task in tasks){
var parent:TaskData = taskIdHash[task.parentId];
// if no parent then root element, i.e push into the return Array
if (parent == null){
rootItems.push(task);
}
// if has parent push into children and originalChildren
else {
parent.children.push(task);
parent.originalChildren.push(task);
}
}
return rootItems;
}
Try this:
AccountData:
public class AccountData
{
public var Id:int;
public var ParentId:int;
public var children:/*AccountData*/Array;
public function AccountData(id:int, parentId:int)
{
children = [];
this.Id = id;
this.ParentId = parentId;
}
}
Code:
private function PutChildrenWithParents(accountData:ArrayCollection):AccountData
{
// dummy data for testing
//var arr:/*AccountData*/Array = [new AccountData(2, 1),
// new AccountData(1, 0), // root
// new AccountData(4, 2),
// new AccountData(3, 1)
// ];
var arr:/*AccountData*/Array = accountData.source;
var dict:Object = { };
var i:int;
// generate a lookup dictionary
for (i = 0; i < arr.length; i++)
{
dict[arr[i].Id] = arr[i];
}
// root element
dict[0] = new AccountData(0, 0);
// generate the tree
for (i = 0; i < arr.length; i++)
{
dict[arr[i].ParentId].children.push(arr[i]);
}
return dict[0];
}
dict[0] holds now your root element.
Maybe it's doesn't have the best possible performance but it does what you want.
PS: This code supposes that there are no invalid ParentId's.
Here's what I ended up doing, apparently you can dynamically add new properties to an object with
object['new_prop'] = whatever
From there, I used a recursive function to iterate through any children so you could have n levels of the hierarchy and if it found anything it would pass up through the chain by reference until the original function found it and acted on it.
private function PutChildrenWithParents(accountData : ArrayCollection) : ArrayCollection{
var pos_inner:int = 0;
var pos_outer:int = 0;
var result:Object = new Object();
while(pos_outer < accountData.length){
if (accountData[pos_outer].ParentId != null){
pos_inner = 0;
while(pos_inner < accountData.length){
result = CheckForParent(accountData[pos_inner],
accountData[pos_outer].ParentId);
if ( result != null ){
if(result.hasOwnProperty('children') == false){
result['children'] = new ArrayCollection();
}
result.children.addItem(accountData[pos_outer]);
accountData.removeItemAt(pos_outer);
pos_inner--;
}
pos_inner++;
}
}
pos_outer++;
}
return accountData;
}
private function CheckForParent(suspectedParent:Object, parentId:String) : Object{
var parentObj:Object;
var counter:int = 0;
if ( suspectedParent.hasOwnProperty('children') == true ){
while (counter < suspectedParent.children.length){
parentObj = CheckForParent(suspectedParent.children[counter], parentId);
if (parentObj != null){
return parentObj;
}
counter++;
}
}
if ( suspectedParent.Id == parentId ){
return suspectedParent;
}
return null;
}

Cannot add an entity that already exists

Code:
public ActionResult Create(Group group)
{
if (ModelState.IsValid)
{
group.int_CreatedBy = 1;
group.dtm_CreatedDate = DateTime.Now;
var Groups = Request["Groups"];
int GroupId = 0;
GroupFeature GroupFeature=new GroupFeature();
foreach (var GroupIdd in Groups)
{
// GroupId = int.Parse(GroupIdd.ToString());
}
var Features = Request["Features"];
int FeatureId = 0;
int t = 0;
int ids=0;
string[] Feature = Features.Split(',').ToArray();
//foreach (var FeatureIdd in Features)
for(int i=0; i<Feature.Length; i++)
{
if (int.TryParse(Feature[i].ToString(), out ids))
{
GroupFeature.int_GroupId = 35;
GroupFeature.int_FeaturesId = ids;
if (ids != 0)
{
GroupFeatureRepository.Add(GroupFeature);
GroupFeatureRepository.Save();
}
}
}
return RedirectToAction("Details", new { id = group.int_GroupId });
}
return View();
}
I am getting an error here Cannot add an entity that already exists. at this line GroupFeatureRepository.Add(GroupFeature);
GroupFeatureRepository.Save();
This line:
GroupFeature GroupFeature=new GroupFeature();
needs to be inside your for loop, like this:
for(int i=0; i<Feature.Length; i++)
{
if (int.TryParse(Feature[i].ToString(), out ids))
{
GroupFeature GroupFeature=new GroupFeature();
You need to add a new GroupFeature each time(e.g. one not in that collection, which your re-used object already is after the first loop). You can't re-use the same GroupFeature object like that for adding, but moving it inside the loop so you generate a distinct GroupFeature each time will resolve this.

Resources