Data access layer with multiple data sources - json

I have a task: I need create data access layer, which can work with multiple data sources (json files, xml files, sql server). But I just have no any idea, how it should be done.
I have tried create my own context by inheriting DBContext class (something like JsonContext), which contains paths to json files and does I/O operations, but now i think it looks kinda stupid :).
Maybe I can create interface of basic repository and implement it with each data source? Or maybe exists patterns or practices, that can help me?

It's not a bad idea to take the DbContext that EntityFramework generates for you, and use that as your common base class for all of the different data sources (JsonContext inherits from DbContext). However, the problem I see with this approach is that when you instantiate a JsonContext, it will call the constructors of the base class, DbContext, and try to connect to SQL Server, which is not what you want.
I don't know if there is an accepted pattern for doing what you're trying to do, so I think you're probably just going to have to invent your own common interface or base class that all the concrete data sources will have to implement.

Related

Is it possible to create a SQL data base using a core data schema

I have a core data schema file with relationships between the entities.
I need to create a SQL database and would like to know if it can be created automatically (MySql or MS-SQL) using only this file.
Looking at the SQLite DB I see that the relationships are not mapped in any logical way.
First, your assessment that the relationships are "not mapped in any logical way" is not correct. If you look carefully at the Core Data generated database you will discover that the relationships are mapped exactly as in any other old relational database scheme, i.e. with foreign keys referring to rows in other tables.
Also, the naming conventions in these SQLite databases are very transparent (e.g., entity and attribute names start with Z, etc.
That being said, I would strongly discourage you to hack the Core Data generated database file, or even to use it to inform another database scheme, the reason being that these are undocumented features that could change any time without notice and thus break any code you write based on them.
IMO, the most practical thing to do is to rewrite the model quickly in the usual MySQL schema format and update it manually as well when you change the managed object model.
If you would like to automate the process, there is a rich set of APIs provided for interpreting and parsing NSManagedObjectModel, including classes like NSEntityDescription, NSAttributeDescription etc. You could write a framework that iterates though your entities and attributes and generates a text file that is a readable schema for MySQL, complete with information about indexing, versions etc..
If you go down that route, please make sure to notify us and do post your framework on Github for the benefit of others.
If you use Core Data you can create an SQL based database using a schema file but its structure is entirely controlled by the Core Data framework. Apple specifically tell us as developers to leave it alone and do not edit it using libsqlite or any other method. If you do then Core Data won't have anything to do with you!
In terms of making your own DB using one of Apple's schema files, I'm sure it is possible, but you'd have to know the inner workings of the Core Data framework to even attempt it.
In terms of making your own SQLite DB then you have to sort out all the relationships and mapping yourself.
I think that mixing and matching Core Data resources and custom built SQLite databases is probably a headache waiting to happen. I have used both methods and find that Core Data is brilliant (especially with iCloud) as long as you're OK with your App being limited to Apple only.

Can you recreate a class with an instance of that class?

I have a database component that I'm trying to make as general as possible. Is it possible to accomplish this:
Take in a custom class that I don't have the definition for
Recreate that class locally from the foreign instance
Basically I can't include the definition of objects that will be stored in the database but I want the database to process the raw data of whatever class passed in, store it, and be able to provide it again as an object.
Ideally I could cast it back to it's custom class when the Object gets back from the database.
It sounds like what you are asking for is serialization.
Serialzation in AS3 is possible through a few different methods. I recommend you refer to this article as it describes the method quite clearly.
To elaborate, once you serialize your object, you send it to the server and pair it with a key in a database. Then you can serialize it back into the original object by downloading it from the server again.
I think you're going to find that there are a lot of pitfalls with what you want to do. I suspect that you'll find over the long haul that you can solve the problem in other ways, since someone, somewhere needs a definition of the Class you're instantiating (you also need to think about what happens if you have two instances with conflicting definitions).
Probably a better way to go is to make your app more data driven--where every object can be built based on the data about it. If you need to be able to swap out implementations, consider storing the Class definitions in external swfs and downloading those based on paths or other information stored in the database. Again, you need to consider what will happen if the implementations collide between multiple swfs.
Can you expand on what you're trying to do? It's easier to give you clearer instructions with more information.

Importing a MySQL schema to Xcode as a CoreData Data Model

I have an existing MySQL database, I would like to import the schema into Xcode and create a Core Data data model.
Is there a way (tool, process) to import the CREATE statements so I don't have to build the models "by hand"?
As an intermediary step I could convert to SQLite, I'm not worried about the relationships, foreign keys etc just auto-generating the Entities (Tables) and Properties (Columns).
Actually I needed the feature so badly too that I have decided to make an OSX utility to do so. BUT... then I found a utility in the Mac Appstore that (partially) solves this problem (it was free for some time, I do not know its current state). Its called JSONModeler and what it does is parsing a json tree and generates the coredata model and all derived NSManagedObject subclasses automatically. So a typical workflow would be:
Export the tables from MySQL to xml
Convert the xml to json
Feed the utility with that json and get your coredata model
Now, for a more complicated scenario (relationships etc) I guess you would have to tweak your xml so it would reflect a valid object tree. Then JSONModeler will be able to recreate that tree and export it for coredata.
The problem here is that entities are not tables and properties are not columns. Core Data is an object graph management system and not a database system. The difference is subtle but important. Core Data really doesn't have anything to do with SQL it just sometimes uses SQL as one its persistence options.
Core Data does use a proprietary sqlite schema and in principle you can duplicate that but I don't know of anyone who has succeeded in a robust manner except for very simple SQL databases. Even when they do, its a lot of work. Further, doing so is unsupported and the schema might break somewhere down the line.
The easiest and most robust solution is to write a utility app to read in the existing DB and create the object graph as it goes. You only have to run it once and you've got to create the data model anyway so it doesn't take much time.

Use LINQ generated classes directly?

LINQ will generate a set of classes from the SQL files. Should these be used directly, or should they be wrapped in another class so the model is not so dependent on the implementation?
You can do it either way. Generally I wrap the Linq to SQL classes in a repository, but if the app is small you can use the repository methods directly.
If the app is larger you can add a business layer.
If you actually need to abstract from your sql database's model, then Linq-To-Sql is probably the wrong choice. Sure, you can make it work (but that isn't what it was made for).
If you need that level of abstraction, you will want to move on to a more "enterprisey" ORM like Entity Framework. They require more configuration, which is used to specify the more intricate mappings that allow your object model and database model to not resemble each other,
On the other hand, if this is overkill then use Ling to Sql. It's simple and it's easy, as long as you can stick with its simplified approach to mappings.
I think it's fine to use the generated model classes directly in your business and presentation tiers - however, I would definitely encapsulate data access for those entities inside a repository pattern of some description (GetOne(), Save(), Search(), Delete() etc).
The main reason for doing so is to 'disconnect' query results before returning them to a calling layer, so that clients don't inadvertently execute queries directly against the database when they use LINQ on returned results. Eg, calling ToList() on an IQueryable<T> will return a local copy of the sequence that can be managed using plain LINQ to Objects.
It also promotes better separation of layers and less coupling, as clients will interact via interface methods on the repository, rather than use LINQ to SQL directly for data access, so if you do decide to chuck LINQ to SQL in favour of the Entity Framework (shudders), it's easier to do the refactoring.
The one exception I would make is when LINQ to SQL objects need to cross a service boundary, ie, sent as data transfer objects to or from a WCF service. In this case, I think it's a good idea to have a separate, light-weight object model that supports serialization - don't send your LINQ to SQL objects directly over the wire.

Multiple DBML files - type sharing?

I have a Client/Server application, where the Client and Server have some common tables (which are kept in synchronisation as part of the application).
We currently store these tables (i.e. FileDetails) in a Shared.dbml file. Until now, any stored proc that returns a result of set of FileDetails, has been placed in the Shared.dbml (even it is a Server-only) SP.
I released that the LINQ to SQL supports a Base Class property on the DBML, and I thought that perhaps I could have a Server.dbml, that extends my Shared.dbml. In theory this would give me a ServerDataContext with all the shared tables and SPs, as well as the server-specific elements. Normally in the SQL designer I would drag and drop the SP, over the FileDetails table to show this is what was returned, however as the class is in a different DBML this is not possible, and in the XML I don't think the ElementType IdRef="1" approach will work (as the ref needs to point to another file)
I found I can get around that problem by editing the XMLs return type manually:
<Function Name="dbo.SELECT_FTS_FILES" Method="SELECT_FTS_FILES">
<Return Type="ISingleResult<DataTypes.FileDetails>" />
</Function>
My question is, does anyone have any experience with this kind of approach, and could point me to further resources? Are there any obvious drawbacks to it (other than than manual XML updates)
All feedback welcome
You could inherit from your datacontext. However in your new datacontext you wouldn't be able to use the linq designer you would have to code things out manually.
Is there any reason you don't want two datacontext?
Inheritance and LinqToSql don't play nice together in general. If you have a deep need for it you should look into another ORM like NHibernate.