我正在尝试开发一对使用相同CoreData数据库的C#应用程序,一个iOS,一个Mac。实际上,桌面应用程序填充它,然后它作为iOS应用程序的一部分进行分发。
我可以使用XCode生成一个.xcdatamodeld
文件,描述我希望数据库看起来像什么。我可以使用momc
将其编译成.momd
文件。我可以将.mom
文件包含在我的Mono项目中,然后将其加载到NSManagedObjectModel
中,我可以从中访问各种实体的所有属性。
我还没想到怎么做是从数据库创建一个类的对象,而不是访问表的属性。有什么建议吗?
澄清一下:我希望能够在XCode中创建一个表/类,称之为Person
。我给它两个字段:Name
和Phone
。我希望能够在Mono中运行与此类似的代码:
using (var context = new NSManagedObjectContext())
{
var me = context.Person.GetByID(1);
me.Name = "Bobson";
context.Save();
}
显然,从数据库中获取并保存它的具体细节将有所不同,但要点就在那里。
答案 0 :(得分:1)
在MonoTouch中使用CoreData并不是很困难。你需要使用momc.exe生成妈妈。我成功地完成了它。
如果将文件放在应用程序目录的顶层(也许其他位置也可以),并将构建操作设置为“BundleResource”(可能其他操作也可以)。实例化UIManagedDocument将导致CoreData自动获取妈妈文件,因此您不需要自己创建它,另外还可以获得iCloud支持的优势。
您必须自己生成类文件。编写一个可以读取xcdatamodel文件并吐出C#的脚本应该很容易。这是它应该如何看的一个例子。
public partial class Photographer : NSManagedObject
{
public static NSString NameKey = (NSString) "name";
public static NSString PhotosKey = (NSString) "photos";
public Photographer(IntPtr handle) : base(handle)
{
}
public string Name
{
get { return (NSString) Runtime.GetNSObject(ValueForKey(NameKey)); }
set { SetValueForKey(value, NameKey); }
}
public NSSet Photos
{
get { return (NSSet) Runtime.GetNSObject(ValueForKey(PhotosKey)); }
set { SetValueForKey(value, PhotosKey); }
}
void SetValueForKey(string value, NSString key)
{
base.SetValueForKey((NSString)(value ?? ""), key);
}
public static Photographer InsertNewObject(NSManagedObjectContext context)
{
return (Photographer) NSEntityDescription.InsertNewObjectForEntityForName("Photographer", context);
}
public static Photographer WithName(string name, NSManagedObjectContext context)
{
Photographer photographer = null;
// This is just like Photo(Flickr)'s method. Look there for commentary.
if (name.Length > 0)
{
var request = new NSFetchRequest("Photographer")
{
SortDescriptors = new[] {new NSSortDescriptor("name", true, new Selector("localizedCaseInsensitiveCompare:"))},
Predicate = NSPredicate.FromFormat("name = %@", new NSObject[] {(NSString) name})
};
NSError error;
var matches = context.ExecuteFetchRequest(request, out error);
if (matches == null || matches.Length > 1)
{
// handle error
}
else if (matches.Length == 0)
{
photographer = InsertNewObject(context);
photographer.Name = name;
}
else
{
photographer = (Photographer) matches.First();
}
}
return photographer;
}
}
public partial class Photo : NSManagedObject
{
public static NSString ImageUrlKey = (NSString) "imageURL";
public static NSString TitleKey = (NSString) "title";
public static NSString UniqueKey = (NSString) "unique";
public static NSString SubtitleKey = (NSString) "subtitle";
public static NSString WhoTookKey = (NSString) "whoTook";
public Photo (IntPtr handle) : base (handle)
{
}
public string ImageUrl {
get { return (NSString)Runtime.GetNSObject(ValueForKey(ImageUrlKey)); }
set { SetValueForKey(value, ImageUrlKey); }
}
public string Subtitle {
get { return (NSString)Runtime.GetNSObject(ValueForKey(SubtitleKey)); }
set { SetValueForKey(value, SubtitleKey); }
}
public string Title {
get { return (NSString)Runtime.GetNSObject(ValueForKey(TitleKey)); }
set { SetValueForKey(value, TitleKey); }
}
public string Unique {
get { return (NSString)Runtime.GetNSObject(ValueForKey(UniqueKey)); }
set { SetValueForKey(value, UniqueKey); }
}
public Photographer WhoTook {
get { return (Photographer)Runtime.GetNSObject(ValueForKey(WhoTookKey)); }
set { SetValueForKey(value, WhoTookKey); }
}
void SetValueForKey(string value, NSString key)
{
base.SetValueForKey((NSString) (value??""), key);
}
public static Photo InsertNewObject(NSManagedObjectContext context)
{
return (Photo) NSEntityDescription.InsertNewObjectForEntityForName("Photo", context);
}
public UIImage Image
{
get {
if (string.IsNullOrEmpty(ImageUrl))
return null;
var imageData = NSData.FromUrl(new NSUrl(ImageUrl));
if (imageData == null)
return null;
return new UIImage(imageData);
}
}
答案 1 :(得分:0)
我相信这就是你所追求的:
public partial class Item : NSManagedObject
{
internal Item(string entityName)
: base(NSEntityDescription)m_managedObjectModel.EntitiesByName.ObjectForKey(new NSString(entityName)), m_managedObjectContext)
其中entityName是MOM中的名称。
答案 2 :(得分:0)
根据@ t9mike的评论(我会接受,如果他能得到答案),我放弃使用CoreData,转而采用更加跨平台的方法。我最终使用Vici CoolStorage作为ORM,虽然我不得不在我的项目中嵌入源代码以使其正常工作。