Saving changes of Entity Framework in Asp.Net - asp.net

I have created an entity Appraiser and there are methods to select values, display data etc.
Now I want to save the changes made after data is displayed, I have a button named SAVE, which will be used to save changes.
I am not able to get how to save the changes of this Entity?
Entity name is Appraiser, and I have created methods like get AppriaserDetails etc in DAL, BL and used them in aspx.cs.
This is my code:
public void UpdateData(Appraiser appId)
{
var Appsave = context.Appraisers.FirstOrDefault(App => App.AppraiserId == appId.AppraiserId);
Appsave.AppraiserName = appId.AppraiserName;
Appsave.AppraiserPhones = appId.AppraiserPhones;
Appsave.AppraiserAppraiserCompanyId = appId.AppraiserAppraiserCompanyId;
Appsave.Address = appId.Address;
Appsave.City = appId.City;
Appsave.ProvinceState = appId.ProvinceState;
Appsave.Email = appId.Email;
context.SaveChanges();
}

If u want to insert new record, then can use
MyContext.Appraisers.AddObject(appraiserEntityObject);
MyContext.SaveChanges();
In case of update
if (appraiserEntityObject.EntityState == EntityState.Detached)
{
// In case of web, we got an existing record back from the browser. That object is not attached to the context yet.
MyContext.Appraisers.Attach(appraiserEntityObject);
MyContext.ObjectStateManager.ChangeObjectState(appraiserEntityObject, EntityState.Modified);
}
MyContext.SaveChanges();
Here MyContext is ur ObjectContext

Related

Get WorkflowDesigner from a ModelItem

I am trying to create a custom IExpressionEditor. In order to new one up I need a WorkflowDesigner, All I have is the ModelItem representing my custom activity. Is it possible to access the WorkflowDesigner from a given ModelItem?
List<ModelItem> variables = new List<ModelItem>();
List<ModelItem> nameSpaces = new List<ModelItem>();
// get the activity from the datacontext
CustomActivityDesigner cad = this.DataContext as CustomActivityDesigner;
// try to get the variables
// look for variables collection cant seem to find them
ModelProperty mp = cad.ModelItem.Properties["Variables"];
if(mp != null && mp.PropertyType == typeof(Collection<Variable>))
{
mp.Collection.ToList().ForEach(i => variables.Add(i));
}
// get name spaces
ModelProperty mp2 = cad.ModelItem.Properties["NameSpaces"];
if(mp2 != null && mp2.PropertyType == typeof(Collection<NameSpace>))
{
mp2.Collection.ToList().ForEach(i => nameSpaces.Add(i));
}
// finally need the WorkflowDesigner object
WorkflowDesigner designer = Modelitem.Root....??? as WorkflowDesigner
// now we have what we need we can create the IExpressionEditor
CustomExpressionEditior ce = new CustomExpressionEditior(designer, variables, nameSpaces)
Following the Using a Custom Expression Editor as reference, it seems you should be able to create a Custom Expression Service (which will be creating the Expression Editor instances) and register it to the Services collection on the WorkflowDesigner.
Once it's registered in the WorkflowDesigner's Services collection, you'll be able to:
Get the editing context for the ModelItem by using ModelItemExtensions.GetEditingContext
Access the Services property of the returned EditingContext
Retrieve the Custom Expression Service you registered on the WorkflowDesginer
Hope it helps!

Create a new record in form LedgerJournalTransCustPaym through x++ code

I need to create a reord in LedgerJournalTrans through x++ code.
While debugging I found out that the class LedgerJournalEngine_CustPayment is used to initiate the form as
LedgerJournalEngine_CustPayment = new LedgerJournalEngine_CustPayment(element)
and later
LedgerJournalEngine.initValue(LedgerJournalTrans);
also after assiging the accountNum the methods executed at the modified() method of datasource field LedgerJournalTrans:AccountNum are element.accountNumModifiedPost(); etc.
While trying to achieve the same through code I am not able to initiate the class LedgerJournalEngine_CustPayment and also the other methods in the form LedgerJournalTransCustPaym that system does.
Pls Help..
Joyce
LedgerJournalEngine* classes are mostly used by the forms to do work and execute code before/after events and datasource actions. What you're trying to do, it would probably just make more sense to complete all of the necessary ledgerJournalTrans fields, then do a .insert(). Here is some code I wrote that will do what you want though using the engine some:
static void Job81(Args _args)
{
LedgerJournalEngine_CustPayment ledgerJournalEngine;
LedgerJournalTable ledgerJournalTable;
LedgerJournalTrans ledgerJournalTrans;
NumberSeq numberSeq;
Voucher voucher;
;
// This just selects the header you are inserting into
select firstonly ledgerJournalTable where ledgerJournalTable.JournalNum == 'GB 0056226';
if (!ledgerJournalTable)
throw error ("Unable to find journal table record");
ledgerJournalTrans.initValue();
numberSeq = NumberSeq::newGetNumFromCode(ledgerJournalTable.VoucherSeries);
if (numberSeq)
{
ledgerJournalTrans.Voucher = numberSeq.num();
voucher = ledgerJournalTrans.Voucher;
}
ledgerJournalTrans.JournalNum = ledgerJournalTable.JournalNum;
ledgerJournalTrans.TransDate = SystemDateGet();
ledgerJournalTrans.AccountType = LedgerjournalACType::Cust;
ledgerJournalTrans.AccountNum = '100003';
ledgerJournalEngine = LedgerJournalEngine::construct(LedgerJournalType::CustPayment);
ledgerJournalEngine.newJournalActive(ledgerJournalTable);
ledgerJournalEngine.accountModified(ledgerJournalTrans);
ledgerJournalTrans.AmountCurCredit = 10;
ledgerJournalTrans.OffsetAccountType = ledgerJournalTable.OffsetAccountType;
ledgerJournalTrans.OffsetAccount = ledgerJournalTable.OffsetAccount;
ledgerJournalTrans.CurrencyCode = CompanyInfo::standardCurrency();
ledgerJournalEngine.currencyModified(ledgerJournalTrans);
ledgerJournalTrans.insert();
if (numberSeq && ledgerJournalTrans.Voucher == voucher)
{
numberSeq.used();
}
else
{
if (numberSeq)
numberSeq.abort();
}
info("Done");
}

How to update an entity without a round-trip? (EF 4)

I tried the following:
public void UpdatePlayer(int id)
{
Player player = new Player() {ID = id};
player.Password = "12";
Entities.Players.Attach(player);
Entities.SaveChanges();
}
No change at the db.
What am I missing?
I think it might be because you're setting the values before you attach the object - the data context will not know what fields have changed. Try:
public void UpdatePlayer(int id)
{
Player player = new Player() {ID = id};
Entities.Players.Attach(player);
player.Password = "12";
Entities.SaveChanges();
}
attach is used for entities that already exist in the database, but you have to attach first, and then edit it, as another poster pointed out.
you should use .Add instead of .Attach if you are creating new items.
FYI Entity Framework 4 - AddObject vs Attach
As already mentioned when you attach entity it is set to Unchanged state so you have to manually set the state to Modified. But be aware that setting the state for whole entity can cause update of all fields. So if your Player entity has more than Id and Password fields all other fields will probably be set to default values. For such case try to use:
Entities.Players.Attach(player);
var objectState = Entities.ObjectStateManager.GetObjectStateEntry(player);
objectState.SetModifiedProperty("Password");
Entities.SaveChanges();
You can also try setting password after attaching the entity:
Entities.Players.Attach(player);
player.Password = "12";
Entities.SaveChanges();
When you attach an entity using Attach method, the entity will go into Unchanged EntityState, that is, it has not changed since it was attached to the context. Therefore, EF will not generate necessary update statement to update the database.
All you need to do is to give a hint to EF by changing the EntityState to Modified:
Entities.Players.Attach(player);
Entities.ObjectStateManager.ChangeObjectState(player, EntityState.Modified)
Entities.SaveChanges();

Error while updating Database record with Entity Framework on ASP.NET MVC Page

I have an ASP.NET Page that updates registered User Address Details for a selected record.
Below is the update method that I am calling from my controller.
When I am calling the ApplyPropertyChanges method, I am getting an error. Did anyone run into the same error while updating the record with Entity Framework?
Appreciate your responses.
Error message:
The existing object in the ObjectContext is in the Added state. Changes can only be applied when the existing object is in an unchanged or modified state.
My Update method:
[HttpPost]
public bool UpdateAddressDetail([Bind(Prefix = "RegUser")] AddressDetail regUserAddress, FormCollection formData)
{
regUserAddress.AD_Id = 3;
regUserAddress.LastUpdated = HttpContext.User.Identity.Name;
regUserAddress.UpdatedOn = DateTime.Now;
regUserAddress.AddressType = ((AddressDetail)Session["CurrentAddress"]).AddressType ?? "Primary";
regUserAddress.Phone = ((AddressDetail)Session["CurrentAddress"]).Phone;
regUserAddress.Country = ((AddressDetail)Session["CurrentAddress"]).AddressType ?? "USA";
miEntity.ApplyPropertyChanges(regUserAddress.EntityKey.EntitySetName, regUserAddress);
miEntity.SaveChanges();
return true;
}
The error is the object is detached from the context, and ApplyPropertyChanges thinks the object is added because it isn't attached. So you would need to query from the data context or get an attached form and then apply the changes then.
HTH.
What Dave Said
+
You need to Attach() the disconnected entity to your object context:
http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.attach.aspx
miEntity.Attach(regUserAddress);
miEntity.SaveChanges();
Just add the following code before miEntity.SaveChanges():
miEntity.Entry(regUserAddress).State = EntityState.Modified;
First select the record (object entity), search by key through the ObjectContext. For example if the search ArticleSet EntitySet called for there to record, and once you get it modified its properties with new values and then call SaveChanges() of ObjectContext.
Example:
ObjectQuery<Article> myArt=Context.ArticleSet.Where myArt = (row => row.ArticleId == value);
myArt.Description=" new value ";
etc. ..
etc ...
Context.SaveChanges ();

Accessing the object/row being edited in Dynamic Data

I'm modifying the "Edit.aspx" default page template used by ASP.NET Dynamic Data and adding some additional controls. I know that I can find the type of object being edited by looking at DetailsDataSource.GetTable().EntityType, but how can I see the actual object itself? Also, can I change the properties of the object and tell the data context to submit those changes?
Maybe you have found a solution already, however I'd like to share my expresience on this.
It turned out to be a great pita, but I've managed to obtain the editing row. I had to extract the DetailsDataSource WhereParameters and then create a query in runtime.
The code below works for tables with a single primary key. If you have compound keys, I guess, it will require modifications:
Parameter param = null;
foreach(object item in (DetailsDataSource.WhereParameters[0] as DynamicQueryStringParameter).GetWhereParameters(DetailsDataSource)) {
param = (Parameter)item;
break;
}
IQueryable query = DetailsDataSource.GetTable().GetQuery();
ParameterExpression lambdaArgument = Expression.Parameter(query.ElementType, "");
object paramValue = Convert.ChangeType(param.DefaultValue, param.Type);
Expression compareExpr = Expression.Equal(
Expression.Property(lambdaArgument, param.Name),
Expression.Constant(paramValue)
);
Expression lambda = Expression.Lambda(compareExpr, lambdaArgument);
Expression filteredQuery = Expression.Call(typeof(Queryable), "Where", new Type[] { query.ElementType }, query.Expression, lambda);
var WANTED = query.Provider.CreateQuery(filteredQuery).Cast<object>().FirstOrDefault<object>();
If it's a DD object you may be able to use FieldTemplateUserControl.FindFieldTemplate(controlId). Then if you need to you can cast it as an ITextControl to manipulate data.
Otherwise, try using this extension method to find the child control:
public static T FindControl<T>(this Control startingControl, string id) where T : Control
{
T found = startingControl.FindControl(id) as T;
if (found == null)
{
found = FindChildControl<T>(startingControl, id);
}
return found;
}
I found another solution, the other ones did not work.
In my case, I've copied Edit.aspx in /CustomPages/Devices/
Where Devices is the name of the table for which I want this custom behaviour.
Add this in Edit.aspx -> Page_Init()
DetailsDataSource.Selected += entityDataSource_Selected;
Add this in Edit.aspx :
protected void entityDataSource_Selected(object sender, EntityDataSourceSelectedEventArgs e)
{
Device device = e.Results.Cast<Device>().First();
// you have the object/row being edited !
}
Just change Device to your own table name.

Resources