Ok here is the deal. using my Model to raise the Child_Update() Method. I know it is not good but im just learing right now. Now i given my Business class as Parameter to Change the already given rows.
It's doin everything fine without any error Messages and there is also no null variable but it's not changing anything in the database.
here i'm using the selectedIndex to choose the right items to update
public void ExecuteAngestellte(object obj)
{
try
{
_selectedIndex.Child_Update(new Farbe { FarbauswahlNr = SelectedIndex.FarbauswahlNr, Kurztext = SelectedIndex.Kurztext, Ressource = SelectedIndex.Ressource, Vari1 = SelectedIndex.Vari1, Vari2 = SelectedIndex.Vari2 });
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
and here's the child update
public void Child_Update(Farbe data)
{
using (var ctx =Csla.Data.ObjectContextManager<TestDBEntities>.GetManager(EntitiesDatabase.Name))
{
var objectStateManager = ctx.ObjectContext.ObjectStateManager;
var _data = new Datenbank.Farbe();
_data.FarbauswahlNr = data.FarbauswahlNr;
_data.Kurztext = data.Kurztext;
_data.Ressource = data.Ressource;
_data.Var1 = data.Vari1;
_data.Vari2 = data.Vari2;
ctx.ObjectContext.SaveChanges();
}
}
thx for help
as far as I can tell, your _data is not part of the datacontext
I am not sure what the variables all mean so here is a simple update I use for a single record with entity framework
public void UpdateTable(int idRecord, YourContext Context)
{
MyRecord = Context.MyTable.Find(idRecord);
myRecord.Column = "New Value";
Context.SaveChanges();
}
so I think you need to do:
var MyData = ctx.ObjectContext.TableName.Find(id)
I am assuming you are using entity framework. Does this help?
Related
i tried this method that I created but it prompts me an error:
Realms.RealmInvalidObjectException:This object is detached. Was it deleted from the realm?'
public void deleteFromDatabase(List<CashDenomination> denom_list)
{
using (var transaction = Realm.GetInstance(config).BeginWrite())
{
Realm.GetInstance(config).Remove(denom_list[0]);
transaction.Commit();
}
}
what is the proper coding for deleting records from database in realm in C# type of coding?
You are doing it the right way. The error message you are getting indicates that the object was removed already. Are you sure it still exists in the realm?
UPDATE:
I decided to update this answer because my comment on the other answer was a bit hard to read.
Your original code should work fine. However, if you want deleteFromDatabase to accept lists with CashDenomination instances that either have been removed already or perhaps were never added to the realm, you would need to add a check. Furthermore, note that you should hold on to your Realm instance and use it in the transaction you created. In most cases, you want to keep it around even longer, though there is little overhead to obtaining it via GetInstance.
public void deleteFromDatabase(List<CashDenomination> denom_list)
{
if (!denom_list[0].IsValid) // If this object is not in the realm, do nothing.
return;
var realm = Realm.GetInstance(config);
using (var transaction = realm.BeginWrite())
{
realm.Remove(denom_list[0]);
transaction.Commit();
}
}
Now, if you want to use identifiers, you could look it up like you do, but still just use Remove:
public void deleteFromDatabase(int denom_id)
{
var realm = Realm.GetInstance(config);
var denom = realm.All<CashDenomination>().FirstOrDefault(c => c.denom_id == denom_id);
if (denom == null) // If no entry with this id exists, do nothing.
return;
using (var transaction = realm.BeginWrite())
{
realm.Remove(denom);
transaction.Commit();
}
}
Finally, if your CashDenomination has denom_id marked as PrimaryKey, you could look it up like this:
public void deleteFromDatabase(int denom_id)
{
var realm = Realm.GetInstance(config);
var denom = realm.ObjectForPrimaryKey<CashDenomination>(denom_id);
if (denom == null) // If no entry with this id exists, do nothing.
return;
using (var transaction = realm.BeginWrite())
{
realm.Remove(denom);
transaction.Commit();
}
}
public void deleteFromDatabase(Realm realm, long cashDenominatorId)
{
realm.Write(() =>
{
var cashDenominator = realm.All<Person>().Where(c => c.Id == cashDenominatorId);
Realm.RemoveRange<CashDenomination>(((RealmResults<CashDenomination>)cashDenominator));
});
}
Which you would call as
Realm realm = Realm.GetInstance(config);
var denom_list = ...
// ...
deleteFromDatabase(realm, denom_list[0].id);
I already made it having this code :) thanks to #EpicPandaForce 's answer.
public void deleteFromDatabase(int denom_ID, int form_ID)
{
//Realm realm;
//and
//RealmConfiguration config = new RealmConfiguration(dbPath, true);
//was initialized at the top of my class
realm = Realm.GetInstance(config);
realm.Write(() =>
{
var cashflow_denom = realm.All<CashDenomination>().Where(c => c.denom_id == denom_ID);
var cashflow_form = realm.All<CashForm>().Where(c => c.form_id == form_ID);
realm.RemoveRange(((RealmResults<CashDenomination>)cashflow_denom));
realm.RemoveRange(((RealmResults<CashForm>)cashflow_form));
});
}
it is now deleting my data without exception :)
I am new at Entity Framework Code first and I am building a small app to get used to it.When the site runs for the first time I access existing catalog values inside the database and display this in a drop down using razor.
public void GetCats()
{
using (context = new RecipeContext())
{
try
{
var query = (from r in context.Catalogues
select r).Distinct().ToList();
catalogues = query.Select(t => t.CatalogueName.ToString()).ToList();
catalogues.Sort();
}
catch (Exception exe)
{
labMessage = exe.Message;
}
}
}
Now when I try to add Catalogue values to the context I get the above error.
public void AddCatalogue(string catalogueName)
{
using(context = new RecipeContext())
{
try
{
catalogueName = catalogueName.ToLower();
var catalogue = new RecipeCatalogue { CatalogueName = catalogueName };
if (context.Catalogues.Where(t => t.CatalogueName == catalogueName).Count() > 0)
{
labMessage = "The value already exists";
CatalogueNameAdded = false;
return;
}
context.Catalogues.Add(catalogue);
context.SaveChanges();
catalogueNameAdded = true;
labMessage = "a new catalogue record was added";
}
catch (Exception exe)
{
catalogueNameAdded = false;
labMessage = exe.Message;
}
}
}
The values are being added to the database however but still get the above exception.
Advice perhaps as to why I get this error. This is my Controller method which calls the above method.
[HttpPost]
public JsonResult AddNewCatalogue(string catalogueName)
{
ViewModel model = new ViewModel();
model.AddCatalogue(catalogueName);
return Json(new { ViewModel = model });
}
Is context a field in your model?
I think you shouldn't assign to a field in a using statement. At the closing brace of the using context will be disposed. If you access that field in another place (without re-assigning) you are accessing a disposed object that might raise the exception you are getting.
Try changing your using statetments like this using (var context = new RecipeContext()).
(note var before context) and drop the field.
Your context is being disposed when the using block where you're performing your query is exited. That's the whole point of the using statement:
using(context = new RecipeContext()) {
// ...
}
// context has been disposed at this point
Instead of a using statement, give your class a field to hold a reference to it.
private RecipeContext _context;
public void GetCats() {
_context = new RecipeContext();
// ...
}
public void AddCatalogue(string catalogueName) {
// Use _context here
}
Just make sure that at some point, you call _context.Dispose(). Also, it's probably better to create the context in the constructor or someplace else that's only called once, prior to performing any operations with it.
Just my 2 cents:
The above answers are correct! If you're using some pattern like a repository, I sugest to implement it as a singleton! This way your objects will not be detached, and you're context will not be disposed!
I have a silverlight mvvm with ria project. I have a UI in which admin users can enter info to create new work orders. However, I am having trouble calling the db and adding a new record to the table. I have no code-behind for the UI, the controls are tied to the model through Commands and Command Parameters. So when a user clicks, 'Add new job' it comes here,
public class EditJobViewModel : ViewModelBase
{
private Job _job;
public Job CurrentJob
{
get { return _job; }
set
{
_job = value;
OnPropertyChanged("CurrentJob");
}
}
public ICommand NewJob
{
get
{
return new DelegateCommand(BeginNewJob, (o) => true);
}
}
public void BeginNewJob(object o)
{
_job = new Job();
//_job.JobNumber = _job.JobID.ToString();
_job.AssignedTo = App.userID;
_job.AddedBy = App.userID;
_job.FileTypeJob = "PDF";
_job.AddedTS = DateTime.Now;
_job.OpenDate = DateTime.Now;
BeginSave(o);
}
}
Where Im having trouble is creating a new record in the 'Job' table. On my breakpoint it returns all the columns it needs to, just not a new 'JobID' which is my primary key. This is how I was supposedly trying to create a new record.
public void BeginSave(object o)
{
if (!IsDesignTime)
{
try
{
if (CurrentJob.EntityState == EntityState.New)
{
CurrentJob.AddedBy = App.userID;
CurrentJob.AddedTS = DateTime.Now;
}
CurrentJob.UpdatedBy = App.userID;
CurrentJob.UpdatedTS = DateTime.Now;
// This is here because of a bug in infragistics grid/Entity Framework
foreach (JobFileType ft in CurrentJob.JobFileTypes)
{
if (ft.EntityState != EntityState.Unmodified)
(ft as IEditableObject).EndEdit();
}
foreach (JobTag tag in CurrentJob.JobTags)
{
if (tag.EntityState != EntityState.Unmodified)
(tag as IEditableObject).EndEdit();
}
//(CurrentJob as IEditableObject).EndEdit();
SubmitOperation s = _context.SubmitChanges();
if (s.HasError)
{ }
}
catch (Exception ex)
{ }
}
}
Except that it never hits the EntityState.new. That's just the way I thought to try it. Im thinking there a way to do it from the 'BeginNewJob' command but unable to find a way to create a new JobID or record in general. The Database already has 10000 records and has multiple users creating jobs, so I need a way to get the last job created (getMaxID()??) and increment appropriately, creating a new job on the spot.
İf you use guid type for id column, you will not need to find next id and this approach will decouple new objects from previous objects.
currently, I'm doing an update similar to as follows, because I can't see a better way of doing it. I've tried suggestions that I've read in blogs but none work, such as
http://msdn.microsoft.com/en-us/library/bb425822.aspx
and
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
Maybe these do work and I'm missing some point. Has anyone else had luck with them?
// please note this isn't the actual code.
// I've modified it to clarify the point I wanted to make
// and also I didn't want to post our code here!
public bool UpdateMyStuff(int myId, List<int> funds)
{
// get MyTypes that correspond to the ID I want to update
IQueryable<MyType> myTypes =
database.MyTypes.Where(xx => xx.MyType_MyId == myId);
// delete them from the database
foreach (db.MyType mt in myTypes)
{
database.MyTypes.DeleteOnSubmit(mt);
}
database.SubmitChanges();
// create a new row for each item I wanted to update, and insert it
foreach (int fund in funds)
{
database.MyType mt = new database.MyType
{
MyType_MyId = myId,
fund_id = fund
};
database.MyTypes.InsertOnSubmit(mt);
}
// try to commit the insert
try
{
database.SubmitChanges();
return true;
}
catch (Exception)
{
return false;
throw;
}
}
Unfortunately, there isn't a database.MyTypes.Update() method so I don't know a better way to do it. Can sombody suggest what I could do? Thanks.
..as a side note, why isn't there an Update() method?
Eh?
public void UpdateCustomer(int CustomerId, string CustomerName)
{
using (MyDataContext dc = new MyDataContext)
{
//retrieve an object from the datacontext.
// datacontext tracks changes to this instance!!!
Customer customer = dc.Customers.First(c => c.ID = CustomerId);
// property assignment is a change to this instance
customer.Name = CustomerName;
//dc knows that customer has changed
// and makes that change in the database
dc.SubmitChanges();
}
}
Ok, I am attempting to use this custom extension to perform an entity update. Right now it should update all properties and then all of its related ends (references). The problem is even though the entity with changes does have a related end with an entity key that is valid and correct (verified in the debugger its there). When the RelationshipManager gets it they key is null.. Anyone see anything wrong with this code?
public static void ApplyChanges(this ObjectContext context, EntityObject entityWithChanges)
{
if (entityWithChanges.EntityState == EntityState.Detached)
{
object entityCurrentlyInDB = null;
if (context.TryGetObjectByKey(entityWithChanges.EntityKey, out entityCurrentlyInDB))
{
context.ApplyPropertyChanges(entityWithChanges.EntityKey.EntitySetName, entityWithChanges);
foreach (var relatedEnd in ((IEntityWithRelationships)entityCurrentlyInDB).RelationshipManager.GetAllRelatedEnds())
{
var oldRef = relatedEnd as EntityReference;
if (oldRef != null)
{
var newRef =
((IEntityWithRelationships)entityWithChanges).RelationshipManager
.GetRelatedEnd(oldRef.RelationshipName, oldRef.TargetRoleName) as EntityReference;
oldRef.EntityKey = newRef.EntityKey;
}
}
}
else
{
throw new ObjectNotFoundException();
}
}
}
This is just a modified version of what I found
Here
Appreciate the help.
UPDATE:
This is the Update Method
public static void UpdateTemplate(Template template)
{
using (TheEntities context = new TheEntities())
{
context.ApplyChanges(template);
try
{
context.SaveChanges();
}
catch (OptimisticConcurrencyException)
{
context.Refresh(RefreshMode.ClientWins, template);
context.SaveChanges();
}
context.RemoveTracking(template);
}
}
This is the unit test:
[TestMethod]
public void CanUpdateATemplate()
{
Template template = new Template();
template.Name = "Test";
template.Description = "Test";
TemplateType type = TemplateManager.FindTemplateTypeByName("Test");
if (type == null)
{
type = new TemplateType();
type.Name = "Test";
}
template.TemplateType = type;
TemplateManager.AddTemplate(template);
template = TemplateManager.FindTemplateByID(template.TemplateID);
Assert.IsNotNull(template);
type = TemplateManager.FindTemplateTypeByName("Round");
if (type == null)
{
type = new TemplateType();
type.Name = "Round";
}
template.TemplateType = type;
TemplateManager.UpdateTemplate(template);
template = TemplateManager.FindTemplateByID(template.TemplateID);
Assert.IsNotNull(template);
Assert.IsTrue(template.TemplateType.Name == "Round");
TemplateManager.DeleteTemplate(template);
template = TemplateManager.FindTemplateByID(template.TemplateID);
Assert.IsNull(template);
}
This is simply not possible due to the way Detach works in EF.
I found that if I added key information myself I could get the generic call to work and even save it.
The problem is that the moment you go to return an entity after calling Detach on it you lose all relationship data. Ive found some write ups on writing graph managers for each entity but I find that a waste seeing as EF should do this stuff (supposedly it will in v2).
EF simply is not ready for N-Tier deployments.