EF4 Rollback Refresh don't refresh store values - entity-framework-4

i have this in EF4:
SomeClass ObjectX;
using (MyBDcontext ctx = ModelHelper.GetObjectContext())
ObjectX = ctx.GetObjectByKey(Entity.EntityKey);
ObjectX.SomeProperty = StoreValue + 1;
using (MyBDcontext ctx = ModelHelper.GetObjectContext()){
//I get the same object
SomeClass AnotherObjectX = (SomeClass)ctx.GetObjectByKey(ObjectX.EntityKey);
//I do a DeepCopy(copyFrom, copyTo)
ModelHelper.DeepCopy(ObjectX, AnotherObjectX);
var objects = (from entry in ctx.ObjectStateManager.GetObjectStateEntries(
EntityState.Modified)
where entry.EntityKey != null
select entry.Entity);
ctx.Refresh(RefreshMode.StoreWins, objects);
}
My problem is that the object ObjectX after run Refresh() is with the same values, not the store values. why?
in var objects exist an instance of ObjectX and is refresh with the store values but my intance not change.
sorry about my english, thanks for the help...
Edit:
thank for the help Gert, i will try to explain my self:
//Store values
ObjectX.SomeProperty = 0
//Edit in memory
ObjectX.SomeProperty = 1
//For some reason i wanna cancel all change and return store values ctx.Refresh(RefreshMode.StoreWins, objects);
//ObjectX.SomeProperty have the value = 1, it's supust to be 0 (store value)

Related

Xamarin iOS - Why Can't I Iterate or Fetch by Index on an NSArray?

I am trying to either iterate over an NSArray in Xamarin, or fetch items by index as follows :
try
{
NSData value = (NSData)NSUserDefaults.StandardUserDefaults["accounts"];
NSKeyedUnarchiver unarchiver = new NSKeyedUnarchiver(value);
NSArray valuesDictionary = (NSArray)NSKeyedUnarchiver.UnarchiveObject(value);
foreach (var x in valuesDictionary)
{
}
if (valuesDictionary != null)
{
var accountList = new List<Account>();
int numberOfOrgs = (int)valuesDictionary.Count;
for (int x = 0; x < numberOfOrgs; x++)
{
var org = valuesDictionary[x];
}
}
However the compiler throws errors both for the iteration and the indexing.
foreach (var x in valuesDictionary)
{
}
errors with "foreach statement cannot operate on variables of type 'NSArray' because 'NSArray' does not contain a public instance or extension definition for 'GetEnumerator'"
and
var org = valuesDictionary[x];
errors with "Cannot apply indexing to a type of NSArray".
Can anyone suggest why this is ? In Objective C I think I'd be able to do both of these things.
Thanks !
For anyone in the future that has this problem, although you can't index on an NSArray, you can use the Xamarin method of :
GetItem<type>(index)
e.g
myArray.GetItem<NSObject>(0).
Works like a charm :)

cannot set obj value from model return

public bool EditNew(News n)
{
News obj = new News();
obj = c.News.Where(p=>p.NewsID == n.NewsID).SingleOrDefault();
obj.NewsTitle = n.NewsTitle;
obj.IsActive = n.IsActive;
obj.IsHot = n.IsHot;
obj.NewsImage = n.NewsImage;
c.SaveChanges();
return true;
}
Not much information to go on, but assuming c is the DbContext object, it looks like you do not have a News object in your DB with the NewsId you are passing in to the EditNew method which results in the LINQ method SingleOrDefault() returning null

Compare objects within Array and put equal values in seperate new object

In my App I have an array of objects 'class: EventObjects' with several properties like 'date: NSDate?' and 'stuffToDo: String?' that are fetched from a calendar database. What I try to achieve now is putting all EventObjects with the same date property together in another object of 'class: EventsAtSameDate'.
class EventsAtSameDate: NSObject
{
var date:NSDate?
var eventObjects:NSArray<EventObject>?
}
And finally have a nested array with the EventsAtSameDate.
var nestedArrayOfEventsAtSameDateObjects: Array<EventsAtSameDate>?
I know how to search and sort an array with .filter .sort .sortInPlace etc. functions. But how can I compare the dates in the array with each other and put them in another nested Array?
You could instantiate a dictionary to keep track of the dates present while doing one iteration over the initial array of type EventObject. Then iterate the the dictionary to instantiate classes of EventsAtSameDate and append them to the nestedArrayOfEventsAtSameDateObjects: [EventsAtSameDate]
The code would look something like:
var nestedArrayOfEventsAtSameDateObjects = [EventsAtSameDate]()
//instantiate a dictionary that uses Date as the key and an array of EventObject as the associated value
var dictionary = [Date: [EventObject]]()
//iterate through your intial array of EventObjects
for obj in eObjs {
//check if you have already seen the date in the collection
if dictionary[obj.date] != nil {
//if you have - then append it to that date
dictionary[obj.date]?.append(obj)
continue
}
//otherwise, add it to the dictionary for a check later in the loop
dictionary[obj.date] = [obj]
}
//then iterate through the dictionary
for (date, eObjs) in dictionary {
if eObjs.count > 1 {
let sameDate = EventsAtSameDate()
sameDate.date = date
sameDate.eventObjects = eObjs
nestedArrayOfEventsAtSameDateObjects.append(sameDate)
}
}
I would sort the array of your events by date and then iterate over them. Check if the date is newer then the previous one and create another storage if so.
class Event {
var date:Date!
}
class EventsList
{
var date:Date!
var events:[Event]!
}
func createEventsLists(sortedEvents: [Event]) -> [EventsList] {
guard sortedEvents.count > 0 else { return [] }
var currentEventList = EventsList()
var result = [currentEventList]
var lastDate = sortedEvents.first!.date
for event in sortedEvents {
let newDate = event.date.compare(lastDate!) != .orderedDescending
if newDate {
currentEventList = EventsList()
result.append(currentEventList)
}
currentEventList.events.append(event)
lastDate = event.date
}
return result
}

Longitude is always zero in image meta data

I am taking a photo using a MediaPicker in Xamarin. I start the geolocation service and then once the picture is taken I send the byte array of the image and the position information to my own platform specific implementation to add the position information in the meta data of the image.
I then save the image as a file and then email it to myself so I can open it in an external application (Picasa) to ensure the GPS information has been stored properly.
The problem I am running into is that the Latitude and Altitude show up fine, but the Longitude is always zero. I have put break points in my app and verified that the meta data is set properly and that all the information has valid values. I am at a loss at what is going on here.
Some of the following code may be redundant or inefficient simply because I have been testing different methods of adding the meta data. I am using the following code in my application in iOS implementation of this meta data adding method:
public byte[] AddPositionInformation(byte[] bytes, SaleScribe.PCL.Services.Geolocation.Position position)
{
var data = NSData.FromArray(bytes);
UIKit.UIImage original = UIKit.UIImage.LoadFromData(data);
CGImageSource myImageSource = CGImageSource.FromData(original.AsJPEG());
var options = new CGImageDestinationOptions();
options.GpsDictionary = new CoreGraphics.CGImagePropertiesGps();
options.GpsDictionary.Latitude = (float)position.Latitude;
options.GpsDictionary.Longitude = (float)position.Longitude;
options.GpsDictionary.Altitude = (int)position.Altitude;
NSMutableData mutableData = new NSMutableData();
using(var dest = CGImageDestination.Create(mutableData, myImageSource.TypeIdentifier, 1, new CGImageDestinationOptions()))
{
dest.AddImage(myImageSource, (int)(myImageSource.ImageCount - 1), options);
dest.Close();
}
return (mutableData as NSData).ToArray();
}
In the function that receives this byte array I am simply writing the byte array directly to a file.
Any help would be very much appreciated.
Thanks!
For anyone who may interested I had to use another method to get this to work, but the underlying problem was that the GPS Lat and Long require a uint so the -94.xxx longitude was invalid. I needed to add the absolute value of the lat and long and then add the appropriate ref value based on the original signed value.
Here is the code that worked for me:
public byte[] AddPositionInformation(byte[] bytes, SaleScribe.PCL.Services.Geolocation.Position position)
{
var data = NSData.FromArray(bytes);
CGImageSource myImageSource = CGImageSource.FromData(data);
var ns = new NSDictionary();
var imageProperties = myImageSource.CopyProperties(ns, 0);
var gps = new NSMutableDictionary();
gps.SetValueForKey(NSObject.FromObject(System.Math.Abs(position.Latitude)), CGImageProperties.GPSLatitude);
gps.SetValueForKey(NSObject.FromObject(new NSString(position.Latitude < 0 ? "S" : "N")), CGImageProperties.GPSLatitudeRef);
gps.SetValueForKey(NSObject.FromObject(System.Math.Abs(position.Longitude)), CGImageProperties.GPSLongitude);
gps.SetValueForKey(NSObject.FromObject(new NSString(position.Longitude < 0 ? "W" : "E")), CGImageProperties.GPSLongitudeRef);
gps.SetValueForKey(NSObject.FromObject(position.Altitude), CGImageProperties.GPSAltitude);
gps.SetValueForKey(NSObject.FromObject(position.Altitude < 0 ? 1 : 0), CGImageProperties.GPSAltitudeRef);
var mutableDictionary = imageProperties.MutableCopy();
mutableDictionary.SetValueForKey(gps, CGImageProperties.GPSDictionary);
NSMutableData mutableData = new NSMutableData();
var dest = CGImageDestination.Create(mutableData, myImageSource.TypeIdentifier, 1);
dest.AddImage(myImageSource, 0, mutableDictionary as NSDictionary);
dest.Close();
return mutableData.ToArray();
}

Subsequent PFObject.saveAll() doesn't work in iOS Swift app

This method is called twice in a row, once for Emails, and again for Phone numbers, in an attempt to save that info to a separate object for each contact as I couldn't figure out how to save nested arrays to a single Parse object.
The baffling thing is that if I only do the method for emails, all save fine. If I only do it for Phone numbers, all save fine. When I do emails and then phones, only phones save. When I do phones and then emails, emails save.
The exception is that if a given contact only has an email or phone it always succeeds. Commenting out the pointer to Contacts didn't do anything to help, so it appears there's some race condition or locking error that's going on here with Parse.
Any ideas? I'd love to learn how to do nested arrays to parse too if that's possible, but I tried a few things and couldn't figure out how to get that to work.
func updateMultiField(person: ABRecord, parseObject: PFObject, fieldToGrab: ABPropertyID, contact: PFObject){
var multiArray:ABMultiValueRef = extractABMultiRef(ABRecordCopyValue(person, fieldToGrab))!
var parseObjects: [PFObject] = [PFObject]()
for (var j = 0; j < ABMultiValueGetCount(multiArray); ++j){
var multi = MultiRef()
var multiValueRaw = ABMultiValueCopyValueAtIndex(multiArray, j)
multi.value = extractMultiValue(multiValueRaw)
if (multi.value != nil) {
//get type
multi.type = getMultiType(fieldToGrab)
//get label
multi.label = extractMultiLabel(ABMultiValueCopyLabelAtIndex(multiArray, j))
//get id
multi.id = String(Int(ABMultiValueGetIdentifierAtIndex(multiArray, j)))
parseObject[parseContactIdFieldName] = contact
parseObject[labelFieldName] = multi.label
parseObject[valueFieldName] = multi.value
parseObject[multiIdFieldName] = multi.id
parseObject[typeFieldName] = multi.type
println("\(multi.type) multi about to be saved with value of \(multi.value)")
parseObjects.insert(parseObject, atIndex: j)
//save
}//if
}//for
PFObject.saveAll(parseObjects)
}//updateField
An earlier method calls this method twice:
updateMultiField(person, parseObject: multis, fieldToGrab: kABPersonPhoneProperty, contact: contact)
updateMultiField(person, parseObject: multis, fieldToGrab: kABPersonEmailProperty, contact: contact)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UPDATE:
Here's the fixed code, which no longer passes a PFObject into the method and tries to save the same object over and over, but rather instantiates it in the for loop (5th line), which resolves the problem:
func updateMultiField(person: ABRecord, fieldToGrab: ABPropertyID, contact: PFObject){
var multiArray:ABMultiValueRef = extractABMultiRef(ABRecordCopyValue(person, fieldToGrab))!
var parseObjects: [PFObject] = [PFObject]()
for (var j = 0; j < ABMultiValueGetCount(multiArray); ++j){
var parseObject = PFObject(className: multisObjectName)
var multi = MultiRef()
var multiValueRaw = ABMultiValueCopyValueAtIndex(multiArray, j)
multi.value = extractMultiValue(multiValueRaw)
if (multi.value != nil) {
//get type
multi.type = getMultiType(fieldToGrab)
//get label
multi.label = extractMultiLabel(ABMultiValueCopyLabelAtIndex(multiArray, j))
//get id
multi.id = String(Int(ABMultiValueGetIdentifierAtIndex(multiArray, j)))
parseObject[parseContactIdFieldName] = contact
parseObject[labelFieldName] = multi.label
parseObject[valueFieldName] = multi.value
parseObject[multiIdFieldName] = multi.id
parseObject[typeFieldName] = multi.type
println("\(multi.type) multi about to be saved with value of \(multi.value)")
parseObjects.insert(parseObject, atIndex: j)
}//if
}//for
PFObject.saveAll(parseObjects)
}//updateMultiField
You seems trying to save the same parseObject 2 times without retrieving it in between. the last save will be always ignored since the object you are trying to save is outdated (a newest version is already on server).
you should retrieve the parseObject from server and then change and save again.

Resources