I currently have an ASP .NET MVC / EF4 project that contains many pieces of autonomous functionality such as a blogging, events, contests, wiki, etc.
The entities used by each system are all mapped to my database through one giant EDM file.
This works well for the main site, but I also have a few personal sites where I want to reuse just the blogging functionality from the mains ite.
My biggest problem is that due to the mac daddy EDM file, my blog sites have to constantly have their database schemas updated to reflect changes made to areas of functionality that they don't use (i.e. changes to the events system).
The only other gotcha is that there are some entities (Users and Tags) that have relationships with entities from each area of functionality, making it hard to simply split each area of functionality off into its own EDM.
With all of this said, I'm trying to figure out the most efficient way to set this up.
Should I go down the road of splitting up the EDMs by each area (blogs, events, contests, wiki) and figuring out a way to maintain relationships for the User and Tag entities?
Or should I just perhaps be creating an EDM for each website that only maps the entities that it will actually need? The only problem with this is that my repository layer takes in a UnitOfWork/ObjectContext, and by creating new ObjectContexts for each site I'd have problems reusing my repository code.
You could setup a WCF service and then pass your data via a JSON contract. That way you'd have a central service that holds your EF data, and then just exposes functions based on what the your different applications need.
Its more short term work to setup (hopefully your service/repository layer was done with IoC in mind to allow it to be easily plugged in) but if your EF data changes a lot, it means you can update the one central service without having to update each of your clients apps.
There's a good reference thread here on S.O: https://stackoverflow.com/questions/973017/where-to-find-good-wcf-video-tutorials
Related
I have the main website that uses a database to store and access user accounts. I'm using EF to manage the schema. I also defined site-specific POCOs and have migrated them to the database.
Now, what if I want a separate website, for example, a resource server (Web API) that would expose (with authorization) the same data set up on the main website?
Do I create the same POCOs and derived DbContext on the resource server again? That seems like duplicating work, though.
What if I wanted to create new POCOs on the resource server and reflect them onto that same database? Wouldn't that conflict with the current migration (which is saved on the database), then subsequently mess up the EF setup on the main website?
I've seen the suggestion of putting the POCOs and DbContexts in a library and have multiple projects reference that same library. This seems viable, however I'd have to hard-code the connection string, which seems dirty to me.
I'm starting to think that EF is probably not recommended for this kind of setup. It seems like a database-first approach plays better here - though I would have to manually reedit the data contexts (most likely, LINQ-SQL) for every database schema change.
Are there any lesser-known capabilities, facts, practices, etc., for/about EF that would help in this situation?
Generally, you can avoid duplication by having one API serving both sites and have resources version for each if needed. On the other hand, if you choose reuse and add approach, creating additional EF code-first entities should not interfere with other site data layer if modeled and mapped carefully. DbContext connection string does not have to be hard-coded.
my next assignments is to build 2 information portals for customers. These portals will be login protected sites and contain a set of pages displaying information like orders, invoices, pdf-files ... for the authenticated user (all presented as lists with links to detail pages). The users and the data are stored in an Oracle database. The portals differ in some of the features and in the layout.
My standard approach is to build an individual ASP.net Web Application for every portal.
But this is not the best way to get something reusable. So for these two projects my idea is to create a set of WCF services to get the Data from the Oracle database and to build user controls to display the different elements in Umbraco. This way I hope to get a set of independent, reusable “modules” which can be used to build these portals.
Now my question: is Umbraco a good platform for this type of projects? And is my “concept” a valid approach?
Kind regards
Volkmar
Umbracois very flexible. ON the one hand there is the question about security: With Umbraco you can use any Membership Provider you want for all visitors ( also with member roles).
On the other hand you have the question of the integration: With Umbraco you can create usercontrols, xslts or razor files as macros (which can be seen as the reusable modules).
For Xslt you can implement your own XsltExtension which pulls the external content as XPathNodeIterator you can use in every Xslt macro. For ascx files or razor you can use LinQ2Umbraco, your own objects etc to connect to the oracle database.
You also can use some sort of caching functionality to reduce the db-calls. On the other hand is one of the biggest advantages that Umbraco stores all the content as xml and object tree in memmory. So it is very fast in content rendering. With every database call you are loosing a little bit of this advantage.
hth, Thomas
Ruben Verbourgh began the Oracle4Umbraco project to create an abstracted fork for the Datalayer to support running on an Oracle DB. You can find it at http://oracle4umbraco.codeplex.com/, although it has no active releases, so build from source and YMMV.
Volkmar, your concept is perfectly sound - although you might want to consider using the Umbraco data store as the persistence layer for your data rather than in the Oracle DB itself. You get XML content versioning, caching, and all the benefits of the content-management side of things, in a robust and flexible framework which you can expose to other apps later should you so need to, through the Umbraco APIs and web services.
HTH,
Benjamin
content management of website becomes simplified with Umbraco.
But if you are planning to use Oracle as backend, Umbraco does not have support for it.
So decide carefully as to what parameters can be compromised.
Good luck.
I'm new to EF4 and haven't had any experience with it before. So, bear with me if this is very simple question.
I have my POCO entities (.tt file) in BOL, the .edmx file (EDM) in DAL and my webapp in Presentation layer. All the business logic goes to BLL layer.
Here are the references:
UI->BLL-DAL-BOL
BLL->DAL-BOL
DAL->BOL
BOL->None of my project.
1- Is my understanding of layers distinction correct? Am I in the right direction?
2- How can I use ASP.NET Membership provider with entities. Should I implement membership, persistence ignorant too and map all user tables in sql server to entities?
2- How can I add custom validation? I don't mean maxlength or valid email..., I mean something like access levels. For example I want certain users be able to modify a field (say productprice) in my website. Where should I use the User.IsInRole method? the BLL doesn't have any reference to user info. should I pass some parameters to BLL (like "bool CanChangePrice") to clarify access levels?
Wow Kamyar, just a few questions wrapped up in this one;-) I'm not sure if I'll cover all the possible ground, but here goes.
ProjectStructure
- generally your structure of projects is correct, and the references you have are correct. Some may argue that you want to separate your concerns a bit and break some of the references, but personally I find your structure workable.
As a practical matter I tend to keep my EDXM and POCOs in the same project. I just have an Entities folder that contains the EDXM and Model.Context.tt, a POCO folder for Model.tt and my Virtual POCO's (below), and a Repository folder for my repository & unit of work.
I also create a file called VirtualPOCOs which is a partial class bound to the POCOs generated by your T4's. My designs tend to be pretty tightly bound to database structure. The VirtualPOCO's give me a little flexibility to deviate from DB design in those one-off situations. Not to much goes in here, just those few very specific needs every project seems to have.
You may also want to consider a repository, table data gateway, or active record setup. All of these patterns will likely be combined with Unit of Work. There are tons of design patterns and your needs or preferences may push you to one or the other. The point here is to shield the upper layers from accessing the EF4 context directly. This way you can centralize connection & transaction management and ensure upper layers are only using POCOs and not accidentally holding on to linq-to-sql objects.
Membership Provider
There is a definitely a schism between the MembershipProvider and EF. You can, however, download the source code for the SQLMembershipProvider and convert it over to use EF. I actually did this conversion. The file is about 1500 lines long, but doesn't have a huge amount of ADO code.
What you didn't ask, but I think I should address, is whether you want to use Membership provider at all. If you're doing basic membership management and roles then the Membership, Roles, and Profile provider can save you a lot of time. For an in depth tour of the capabilities check out the series over at 4GuysFromRolla (https://web.archive.org/web/20211020202857/http://www.4guysfromrolla.com/articles/120705-1.aspx).
If your needs are more complex then, IMHO, the membership provider breaks down pretty quickly. For example, when a user registers for your site you immediately have to create rows in a handful of different tables. Well, the membership provider is registered through webconfig and uses the membership provider interface. It only accepts certain fields in the create function. So what's a boy to do? Well, you can open a larger scale transaction up in your controller, run the membership providers add user function, run your own MyCustomUserStuff(), then commit the transaction. Two reasons I find this unappealing are that I've now got transactional code seeping way up my call stack and if all I need to do is add a few extra fields I've now doubled my database calls needlessly.
I guess I just found the membership provider pretty restricting, and once got in there and made my own custom membership provider the benefits of using MS's model quickly fell away.
Validation
I think the answer here is a resounding --it depends. Are your permissions pretty static? i.e. those in the "SiteManagers" group can edit all over the site? Or are your permissions much more fine grained? Meaning SiteManagers have access to these 75 fields spread across these 22 tables, or is it more table based? Additionally, how mutable are the permissions ? Does your site admin need to be able to frequently turn access on/off or off to various fields in different tables?
I think I need to hear more on your requirements for a specific answer. Keep in mind that the more fine grained you make your permissions the more of a configuration headache the client will have understanding & managing all the permissions.
Also, what back-end are you using? Many DBA's face these decisions. One often used strategy in that world is to create a series of views where each view exposes the columns users have. For example, the EmployeesHR view would expose just those columns that HR people have access to, and the EmployeeDirectory would expose just those fields that the directory has access to.Then HR users are given permission to the HR view, but not the underlying table. Just a thought.
Anyway, hope this helps.
1- Your distinction of the layers seem correct to me.
I wouldn't reference the DAL in the UI, as in my projects, I prefer that only the middle layer access the DAL. But it's not wrong.
So you seem in the right direction.
2- To my knowledge there is no MembershipProvider that works with EF.
So in projects where we used Membership, here is what we did :
created the tables with the aspnet_regsql.exe
configure the Web.Config to use the SqlMembershiptProvider
added in the web.config ANOTHER connection string (one for Membership and one for EF)
Built the EDMX file with all tables, including the Membership ones.
In the code, a UserManager / RoleManager (BLL or DAL it depends on your architecture) get the informations using standard Membership methods. And always use the Membership objects, not EF ones. So in fact the user / roles management part is separated from the EF.
We only use the aspnet_* EF entities when there is a link between your custom tables and a Membership table (for instance, when you want to link one of your table with the aspnet_Users table to keep a reference of the user that inserted a data).
3- For the right management, I would use a BLL RightManager that would allow the UI to know if the user can change the field (so you can disable it, or prevent input), and to use this information in your validation method.
In my project I use a Right table and I associate a Right with a Role. In the RightManager provide a RequestRight(Right) method.
If your Right management is too simple to create tables, just use User.IsInRole() in your RightManager (so I would use it in BLL).
I would place the validation method in the UI if it is "basic" and in the BLL if it contains more complex rules (involving DAL access for instance).
about EF & Membership
as i know, you dont need to use any db provider instead of membership provider
but if you want, you can map membership tables in EF and create additional method to
common provider
I am in the early stages of planning a conversion of a large classic ASP database application to ASP.Net and I'm having trouble picking out which data access method to use. I have played around with Linq To SQL, Dynamic Data, strongly typed datasets, Enterprise Library (Data Access Application Blocks), and a tiny bit with Entity Framework, but none of them have jumped out to me as "the one". There are just too many choices - my head is swimming, help me choose!
Perhaps it would help to give some background on the application that I am converting along with the priorities...
The back end is Microsoft SQL Server (2005 or later) and we are committed to that, so I don't need to worry about ever supporting a different database platform.
The database is very mature and contains a great deal of the business logic. It is highly normalized and makes extensive use of stored procedures, triggers, and views. I would rather not reinvent two wheels at the same time, so I'd like to make as few changes to the database as possible. So, I need to choose a data access method that is flexible enough to let me work around any quirks in the database.
The application has many data entry forms and extensive searching and reporting capabilities (reports are another beast which I will tackle later).
The application needs to be flexible enough to deal with minor changes to the database structure. The application (and database) may be installed at different sites where minor custom modifications are made to the database. Ideally the application could identify the database extensions and react appropriately. In other words, if I need to store an O/R mapping in the application, I need to be able to swap that out (or refresh it easily) when installing the application and database at a new site.
Rapid application development is critical. Since the database is already done and the user interface is going to closely match the existing application, I'm hoping to find something where we can crank this out fairly quickly. I am willing to sacrifice not using the absolute latest and greatest technology if it will save time in development. In other words, if there is a steep learning curve to using something like Entity Framework, I'm fine with going something like strongly typed Datasets and a custom DAL if it will speed up the process.
I am a total newbie to ASP.Net but am intimately familiar with Classic ASP, T-SQL and the old ADO (e.g. disconnected recordsets). If any of the data access methods is better suited for someone coming from my background, I might lean in that direction.
Thanks for any advice that you can offer!
Look at all three articles in this series:
High Performance Data Access Layer Architecture Part 1
Great advice.
You may want to look at decoupling the database layer from the asp layer so that you can not only give more flexbility in making the decision, but when you have to make changes to a customer's database you can just swap in a new dll without changing anything else.
By using dependency injection you can use xml to tell the framework which concrete class to use for an interface.
The advantage to doing this is that you can then go with one database approach, and if you later decide to change to another, then you can just change the dll and go on without making any changes to other layers.
Since you are more familiar with it why not just go directly to the database at the moment by making your own connections? Then you can move the rest of your code and along the way you can decide which of the myriad of technologies to use.
For a new application I am working on I am starting with LINQ to SQL for it, mainly because development will be quicker, but, later, if I decide that won't meet my needs I will just swap it out.
nHibernate might be a good fit. You can store the mapping in external configuration files which would solve your needs. Another option might be using ActiveRecord, which is based upon nHibernate.
nHibernate has a neat feature which you might find helpful. It's called a Dynamic property which is basically a name value pair collection populated by pulling the column names from the mapping file. So when you add a column at your client site, you update the mapping file and you'd be able to access the data through a collection on the object.
I have an intranet application that needs contact information for various locations on our campus that are served by our IT lab support organization. We have an enterprise directory that contains contact information so I'm not keeping the actual contact information in the database, but rather an immutable identifier that serves as a key to look the person up in our enterprise directory (via a web service). I'll be looking contact information up via a publicly available web site.
The problem comes in that the id that is useful to the web-based directory lookup is only "sort of" immutable and is not the id that I will store in the database. Directory lookups are most easily performed using the person's Active Directory login id. What I will be using is called the Master Records Unique ID.
My question is: where is the most reasonable place to do the translation from MRUID to Active Directory login id for the link?
Right now I'm doing the translation in the presentation layer, with application-level caching to reduce look ups to the directory. Currently there is only a single web site, but I would expect that if there are other web sites that need to do this, I would migrate the helper class to a shared web controls library.
I considered putting the code in the data or business layer, but opted not to because of the caching. How and what you cache seems to be more a function of the application rather than these other layers.
I'd be interested in other opinions and ideas that I may not have considered.
When faced with something that needs to be in the presentation layer of an asp.net web site or web application, but it also may have value in other asp.net web applications I find it useful to create a special class library that has a dependency on the system.web namespace.
Specifically, it will make use of HttpContext.Current to interoperate with the web site that is hosting the library. I'm not sure, but I generally think of this as a business layer assembly, but one that assumes it is hosted in a web context.
I keep my true business code (code that might be used in a non-web application) in a third assembly.
Having an assembly that depends on the web context allows you to use HttpContext.Current to find out what is going on with request and response objects as well as allowing you to interact with the asp.net cache API and related stuff. But it also keeps the code portable for use in more than one web application too.
Generally this web-dependent assembly is also where my HttpModules and HttpHandlers live too.
Keep in mind though that "layers" are logical concepts, not physical ones. There is nothing wrong with an assembly that contains business, DAL, and even presentation layer classes together. The classes themselves shouldn't mix up their roles, but a single assembly can contain classes from different logical layer in your design.
You could place it in your business layer and still use caching, either using the Enterprise Library Caching Application Block in the business layer, or by caching the value returned by the business layer in the ASP.Net cache in your presentation layer.
As it's coming from a different location to your other data I wouldn't put it in the same data access layer as the other database code.
I discussed this issue with some other developers at work and we decided that the presentation layer was the right place to do the translation. Consider the case where different applications that use the same business/data access layers want to translate the data in different ways. Unless we have a clearly defined business rule that states that individual identities shall always be displayed in a certain form, I think I'll leave it where it is and migrate it to a web controls library as needed to support multiple front-ends.