0

我正在尝试开发一对 C# 应用程序,一个 iOS,一个 Mac,它们使用相同的 CoreData 数据库。实际上,桌面应用程序填充它,然后它作为 iOS 应用程序的一部分分发。

我可以使用 XCode 生成一个.xcdatamodeld文件,描述我希望数据库的外观。我可以用它momc来编译成一个.momd文件。我可以将其中的.mom文件包含到我的 Mono 项目中,然后将其加载到 aNSManagedObjectModel中,从中我可以访问各种实体的所有属性。

我还没有弄清楚如何从数据库中创建一个类的对象,而不是访问表的属性。有什么建议么?


澄清一下:我希望能够在 XCode 中创建一个表/类,调用它Person。我给它两个字段:NamePhone. 我希望能够在 Mono 中运行与此类似的代码:

using (var context = new NSManagedObjectContext())
{
  var me = context.Person.GetByID(1);
  me.Name = "Bobson";
  context.Save();
}

显然,从数据库中获取它并将其保存回来的细节会有所不同,但要点就在那里。

4

3 回答 3

1

在 MonoTouch 中使用 CoreData 并不难。您需要使用 momc.exe 生成妈妈。我已经成功地做到了。

如果您将文件放在应用程序目录的顶层(可能其他位置也可以使用)并且您将构建操作设置为“BundleResource”(可能其他操作也可以使用)。实例化 UIManagedDocument 将导致 CoreData 自动获取 mom 文件,因此您无需自己创建它,而且您还可以获得 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);
        }
    }
于 2013-04-25T13:04:13.790 回答
0

我相信这就是你所追求的:

public partial class Item : NSManagedObject
{
   internal Item(string entityName)
      : base(NSEntityDescription)m_managedObjectModel.EntitiesByName.ObjectForKey(new NSString(entityName)), m_managedObjectContext)

其中 entityName 是来自 MOM 的名称。

于 2012-09-24T12:38:29.500 回答
0

根据@t9mike 的评论(如果他给出答案,我会接受),我放弃了使用 CoreData 以支持更跨平台的方法。我最终将 Vici CoolStorage 用于 ORM,尽管我必须将源代码嵌入到我的项目中才能使其正常工作。

于 2012-10-25T19:19:00.583 回答