I have silverlight application, where I use Entity Framework(PostgreSQL) and WCF(not RIA).
Here is the problem:
in database I have table organization and table of contacts. Organization has set of contacts.
EF entity is not a data contract used by wcf. I use convertor to make datacontract from entity and vice versa. So my question is how to save related entities like hibernate saveupdate(cascade="save-update")?
Entity framework doesn't have cascade updates. You must manually handle changes = you must manually decide which contracts were modified, which were added and also wich were deleted. MS decided to solve this inconvinience by introducing Self tracking entities but they are not always bullet proof and are harder to use in Silverlight because STEs code must be shared among client and server.
Related
I'm planning to develop a web application in CakePHP that shows information in graphics and cards. I chose CakePHP because the information that we need to show is very structured, so the model approach makes easier to manage data; also I have some experience with MVC from ASP.NET and I like how simple is to use the routing.
So, my problem is that the multiple organizations that could use the app would have their own database with a different schema that the one we need. I can't just set their string connection in the app.php file because their database won't match my model.
And the organization datasource couldn't fit my model for a lot of reasons: the tables don't have the same name, the schema is different, the fields of my entity are in separated tables, maybe they have the info in different databases or also in different DBMS!
I want to know if there's a way to make an interface that achieves this
In such a way that cakephp Model/Entity can use data regardless of the source. Do you have any suggestions of how to do that? Does CakePHP have an option to make this possible? Should I use PHP with some kind of markup language like JSON or XML? Maybe MySQL has an utility to transform data from different sources into a view and I can make CakePHP use the view instead of the table?
In case you have an answer be as detailed as you can.
This other options are possible if it's impossible to make the interface:
- Usw another framework that can handle this easier and has the features I mentioned above.
- Make the organization change their database so it matches my model (I don't like this one, and probably they won't do it).
- Transfer the data in the application own database.
Additional information:
The data shown in graphics are from students in university. Any university has its own database with their own structure and applications using the db, that's why isn't that easy to change structure. I just want to make it as easy as possible to any school to configure their own db.
EDIT:
The version is CakePHP 3.2.
An important appointment is that it doesn't need all CRUD operations, only "reading". Hope that makes the solution easier.
I don't think your "question" can be answered properly, it doesn't contain enough information, not enough details. I guess there is something that will stay the same for all organizations but their data and business logic will be different. But I'll try it.
And the organization datasource couldn't fit my model for a lot of reasons: the tables don't have the same name, the schema is different, the fields of my entity are in separated tables, maybe they have the info in different databases or also in different DBMS!
Model is a whole layer, so if you have completely different table schemas your business logic, which is part of that layer, will be different as well. Simply changing the database connection alone won't help you then. The data needs to be shown in the views as well and the views must be different as well then.
So what you could try to do and what your 2nd image shows is, that you implement a layer that contains interfaces and base classes. Then create a Cake plugin for each of the organizations that uses these interfaces and base classes and write some code that will conditionally use the plugin depending on whatever criteria (guess domain or sub-domain) is checked. You will have to define the intermediate interfaces in a way that you can access any organization the same way on the API level.
And one technical thing: You can define the connection of a table object in the model layer. Any entity knows about it's origin but you should not implement business logic inside an entity nor change the connection through an entity.
EDIT: The version is CakePHP 3.2. An important appointment is that it doesn't need all CRUD operations, only "reading". Hope that makes the solution easier.
If that's true either use the CRUD plugin (yes, you can use only the R part of it) or write some code, like a class that describes the organization and will be used to create your table objects and views on the fly.
Overall it's a pretty interesting problem but IMHO to broad for a simple answer or solution that can be given here. I think this would require some discussion and analysis to find the best solution. If you're interested in consulting you can contact me, check my profile.
I found a way without coding any interface. In fact, it's using some features already included in the DBMS and CakePHP.
In the case that the schema doesn't fit the model, you can create views to match de table names and column names from the model. By definition, views work as a table so CakePHP searches for the same table name and columns and the DBMS makes the work.
I made a test with views in MySQL and it worked fine. You can also combine the data from different tables.
MySQL views
SQL Server views.
If the user uses another DBMS you just change the datasource in app.php, and make the views if it's necessary
If the data is distributed in different DBMS, CakePHP let's you set a datasource for each table, you just add it to app.php and call it in the table if it's required.
Finally, in case you just need the "reading" option, create a user with limited access to the views and only with SELECT privileges.
USING:
CakePHP 3.2
SQL SERVER 2016
MySQL5.7
I using MS SQL Server with C# and Entity Framework.
The data-tier have one repository for every table that handle Save, Delete, Get etc.
Then i have a business layer that helps the user interface with data transactions and error handling and so on.
In one of the column in database i need to do a calculation before save.
Should i override the Add/Update method in the data-tier and do this calculation or should this be placed in business tier.
Thanks in advice.
In a fine grained, well scaled application design, respecting to standard specifications AKA SOA, any entity has its own service(business) layer and persist layer objects.
When User-interface layer calls a service, the service is receiving a simple or composite DTO that may be mapped to one or more separated database entities, it is allowed in service layer to call other entities service, and you are not allowed to call other entities persist layer objects.
Following the approach:
If the calculation of property A1 in entity A is based on properties of entity A then you may do the calculation on persist layer. If The calculation of property A1 in entity A is based on other entities properties then you have to do the calculation in service layer.
I'd like to log all changes made an SQL Azure database using Entity Framework 4.
However, I failed to find a proper solution so far..
So far I can track all entities themself by overriding SaveChanges() and using the ObjectStateManager to retrieve all added, modified and deleted entities. This works fine. Unfortunately I don't seem to be able to retrieve any useful information out of RelationshipEntries. In our database model we some many-to-many relationships, where I want to log new / modified / deleted entries too.
I want to store all changes in an Azure Storage, to be able to follow changes made by a user and perhaps roll back to a previous version of an entity.
Is there any good way to accomplish this?
Edit:
Our scenario is that we're hosting a RESTful WebService that contains all business logic and stores the data in the Azure SQL Database. A client must be authenticated as a user with the WebService, and I'd need to store the information which user changed the data.
See FrameLog, an Entity Framework logging library that I wrote for this purpose. It is open-source, including for commercial use.
Even if you don't want to use the library, you can look at the code to see one way of handling logging relationships. It handles all relationship multiplicities.
Particularly, see the code for the private methods logRelationshipChange, and logForeignKeyChange in the ChangeLogger class.
You can do it with a tracing provider.
You may want to consider just using a database trigger for this. Whenever a value in a table is changed, copy the row to another Archive table. It has worked pretty well for me.
Let me set up my LOB scenario.
I am re-writing our core business app. The requirements are that I create an internally usable app (I'd like to use Silverlight) that our employees use on a daily basis. I also need to provide a SOAP service that can be used to input orders, get invoices, etc.
I also will be doing this in pieces, so when I update a record in the new SQL Server database, I need to make sure to update our legacy SQL Server as well.
So, it certainly makes sense to create a DAL that will pull data from the new SQL server, as well as write back to 2 data stores.
It would also make sense to create a BLL that can be used by both Silverlight/RIA and the WCF web services.
I have created a data entity of the new database in it's own project and it is used in all the other projects. The problem here is that RIA seems to require that I create it right inside the ASP.Net project in order to get the metadata for Silverlight. Without this, I need to manually re-create the metadata for Silverlight to access it correctly.
My question then, should I create duplicates of the Entity Model? One for RIA and one for everything else? Is there a better way to do this? Should I just forego using RIA and have Silverlight access WCF services? Or should I just continue to duplicate the metadata in RIA?
We use entities for direct reference to storage and Data Transfer Objects (DTOs) which are almost identical for passing back/forth between BLL and WCF/GUI/etc. We map between the 2 using AutoMapper which means there's very little additional work but we don't have to worry about if a given entity is attached to the context/tracking state changes/etc...
Edit: You definitely want to keep your code as DRY as possible. Personally, I'd look at using DTOs above the BLL and either having 2 sets of repositories which are co-ordinated in the DAL (one RW, one W only). or even having Meta-repositories which handle the datasets on the 2 stores themselves.
If you're not already using it, Unity and IoC would be of real benefit to you here. You might also want to use one of the modular code patterns to allow you to register [n] data stores in different modes, so that when you finally want to retire the old store, you don't need to do much work.
I'd also question whether your entities need to be defined in ASP.Net - you may simple be able to reference the appropriate DLLs from your entity/DTO project and add the appropriate markup/config
I'm a little confused here.
I have my POCO classes created with the entity framework modeled from the datbase.
Obviously, I'd like to use these classes in the client too (and any bookkeeping on them would be nice if I'd like to send them back and re-attach)
I looked through the classes generated for the WCF service reference and it seems a bit verbose to be sending over the internet, but it doesn't look like there's anything risky in there security-wise.
And yet, I can't find anything online about doing this. Am I going down a completely awful path?
Help?
EDIT : I suppose they're technically they're not POCO classes if i had them generated by the EntityFramework from the database; just to clear up any possible confusion.
This is a difficult question to answer without knowing more details about your system, but ultimately whether exposing your EF entities in the WCF service contract is the right path or not is influenced by the scope and requirements of the application you are developing.
Perhaps ask yourself the following questions which will hopefully guide your decision:
Is it likely your relational model and object model will need to diverge? This can be driven by a number of factors, but most commonly reporting requirements may enforce a certain design on your database schema (for performance) that you do not want to reflect in your application object model. Using the DB generated EF entities throughout the application layers can bind you to this database design
Are you concerned that changes to your database schema may require your clients to regenerate their service references? Again, using the EF entities throughout your application tiers means any changes implemented in your DB schema (whether of concern to the client or not) may bubble up to the service interface, potentially breaking client compatability with that interface
Is performance a concern? As you mentioned, the generated classes are verbose. You are likely to be transporting unnecessary baggage across the wire, which could be optimized.
Are you concerned about exposing the implementation details of your database schema and persistence mechanism on the wire and to your clients? Given you have generated the model from the database there are likely to be properties that expose information about your schema and persistence mechanism that are redundant from a client's perspective.
In summary there may be a limited number of cases where exposing the EF entities may be acceptable but typically I would design for change and implement some sort of pattern where you map your EF entities to light-weight "persistence-ignorant" POCOs at your repository layer. EF 4.0 does provide the ability to code up a context that returns POCOs, but on my current project we use the codegen'd context and then use automapper to map the EF entities to our data contracts. Outside of the repository layer nothing is aware of the EF entities and I feel this allows for a more maintainable and robust design.