"Injecting" a WHERE clause dynamically w/ PetaPoco - asp.net-mvc-3

I'm building a multi-tenant app with a shared database using .NET MVC 3 and PetaPoco.
The tenant id (along with other info) is saved in a FormsAuth cookie on login and is available to all controllers via a BaseController property. Most tables, (i.e. apart from apart the main 'Tenants' table) include a TenantId column.
Instead of manually adding a 'WHERE TenantId = X' to all CRUD on the feature tables, is there a way I can dynamically add this to the query just before its executed? In other words, maybe maintain a list of tables, and if the query is for one of those tables, then dynamically add in the TenantId filter?
The benefit of course is that it removes the need to add in the filter manually thus reducing the chances its left out. I did find an example using NHibernate, which I doubt can be repurposed. I am using Ninject in case that makes a difference.

There is an OnCommandExecuting method on the Database class which you can override in your own sub class, and modify the sql as you wish just before it gets executed. We use this feature for converting isnull/nvl between Sql Server and Oracle.
You could just leave a marker in your sql and replace it here.

Related

Joining tables in two separate databases with .Net Core 2.1 / EF Core

I have a .Net Core 2.1 Web API which talks to two MySQL databases. Therefore I have two DbContexts, each with a connection string pointing to the relevant database.
In one of my controller actions, I need to return data which requires a join between two tables, one from each database. Is it possible to do this?
As an example, a simple controller action to retrieve data might look something like this:
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return _context.Employees
.Include(e => e.Departments);
}
That example uses one controller only, because in that example both the employee and department tables are in the same database, and therefore both their DbSets would be in the same DbContext.
But what if the employee table was in one database and department table was in another? Then the DbSets for employee and department would be defined in different DbContexts. How could I handle the join in that case? (So that in the example above, the "Include" works properly?
I would imagine that I would have to inject both DbContexts into this controller. But I'm not sure where to go from there...
In my case, both datbases are MySQL databases, and both are on the same server, so that is the only scenario I'm interested in.
After more research, it looks like I could maybe use raw SQL to achieve this. However, what I ended up doing is creating a view on the server which does all the necessary joins, and then I simply call this view...

LINQ DataContext Object Model, could it be used to manage a changing data structure

I am currently working on a project where we are rewriting software that was originally written in Visual DataFlex and we are changing it to use SQL and rewriting it into a C# client program and a C#/ASP.Net website. The current database for this is really horrible and has just had columns added to table or pipe(|) characters stuck between the cell values when they needed to add new fields. So we have things like a person table with over 200 columns because stuff like 6 lots of (addressline1, addressline2, town, city, country, postcode) columns for storing different addresses (home/postal/accountPostal/ect...).
What we would like to do is restructure the database, but we also need to keep using the current structure so that the original software can still work as well. What I would like to know is would it be possible using Linq to write a DataContext Object Model Class that could sort of interpret the data base structures so that we could continue to use the current database structure, but to the code it could look like we where using the new structure, and then once different modules of the software are rewritten we could change the object model to use the correct data structure???
First of all, since you mention the DataContext I think you're looking at Linq to SQL? I would advice to use the Entity Framework. The Entity Framework has more advanced modeling capabilities that you can use in a scenario as yours. It has the ability to construct for example a type from multiple tables, use inheritance or complex types.
The Entity Framework creates a model for you that consists of three parts.
SSDL which stores how your database looks.
CSDL which stores your model (your objects and the relationships between them)
MSL which tells the Entity Framework how to map from your objects to the database structure.
Using this you can have a legacy database and map this to a Domain Model that's more suited to your needs.
The Entity Framework has the ability to create a starting model from your database (where all tables, columns and associations are mapped) en then you can begin restructuring this model.
These classes are generated as partial so you could extend them by for exampling splitting the database piped fields into separate properties.
Have you also thought about using Views? If possible you could at views to your database that give you a nicer dataschema to work with and then base your model on the views in combination with stored procedures.
Hope this gives you any ideas.

Adding columns to DB after publishing using EF CodeF and mvc nugget Scaffold

I have created a web site using mvc 3 and Ef code first , now after publishing the site and it's DB I have found out that I need to add a new columns to one of my DB table,
(the DB already has a lot of data in it )
should I add the columns direct to the DB or should I add to the class?
(just a simple string with get and set)
And how can I do it without losing my data in the DB ?
thanks
Adding the columns to the class should be enough. Evidence you can find here.
Here is the full list of changes that migrations can take care of automatically:
Adding a property or class
Nullable columns will be assigned a value of null for any existing rows of data
Non-Nullable columns will be assigned the CLR default for the given data type for any existing rows of data
Renaming a property or class
See ‘Renaming Properties & Classes’ for the additional steps required here
Renaming an underlying column/table without renaming the property/class
(Using data annotations or the fluent API)
Migrations can automatically detect these renames without additional input
Removing a property
See ‘Automatic Migrations with Data Loss’ section for more information
I suggest you to add the columns direct to the DB and to the class, and test it on the local machine.

MVC3, EF4, and Using blocks

Advocation for using blocks with Entity Framework seems to be popular, but this tutorial for MVC show the Object Context for the Entity being created once at the class level. I ran into the latter first, so I had been using it. I am now trying to switch to the using block method to see if it really is faster, but am running into this error on the view:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
The view is trying to access a collection that was created by this:
homeView.UserList = new SelectList((from n in db.Users where n.US_INACTIVE == 0 orderby n.US_FULL_NAME select n).AsEnumerable(), "US_USER_ID", "US_FULL_NAME");
I don't understand why it is still trying to access the object context from the view (when it uses that SelectList) when it should have been populated in the controlled. Even more confusing, is this same problem does not occur for other database-populated data, which appears to make it into the view just fine.
That aside though, what do I need to do to get data from a using block into the view properly? Or, is a using block the wrong way to go for MVC, and should I just keep using once object context for the class?
You probably didn't call .ToList at the end of your expression so you are not eagerly executing any query but only building query expressions. It is only once the view is executed that the query is implicitly executed, but that happens long after your controller life has ended as well as any data contexts.
This being said I consider passing domain models to views as a bad practice. You should be using view models which are classes specifically designed to the requirements of a given view.
Ayende Rahien has a series of blog posts about the issues of view models. The view model that you pass to the view from the controller must contain all the necessary properties eagerly initialized and loaded with data and this independently of the data access technology you are using. And by the way it's not the controller's responsibility to manage your EF data contexts lifetime. That's should be specific to your data access layer (the repository).
Are you using another table in your view that is related to Users? In your current query only the Users table will be populated and accessing data in any related table will throw that error.
homeView.UserList = new SelectList((from n in db.Users.Include("Other Table") where n.US_INACTIVE == 0 orderby n.US_FULL_NAME select n).AsEnumerable(), "US_USER_ID", "US_FULL_NAME");

.NET 3.5 Linq Datasource and Joins

Have been trying out the new Dynamic Data site create tool that shipped with .NET 3.5. The tool uses LINQ Datasources to get the data from the database using a .dmbl context file for a reference. I am interseted in customizing a data grid but I need to show data from more than one table. Does anyone know how to do this using the LINQ Datasource object?
If the tables are connected by a foreign key, you can easily reference both tables as they will be joined by linq automatically (you can see easily if you look in your dbml and there is an arrow connecting the tables) - if not, see if you can add one.
To do that, you can just use something like this:
<%# Bind("unit1.unit_name") %>
Where in the table, 'unit' has a foreign key that references another table and you pull that 'unit's property of 'unit_name'
I hope that makes sense.
(EDIT misunderstood the question, revising my answer to the following)
Your LinqDataSource could point to a view, which allows you to overcome the problem of not being able to express a Join in the actual element. From "How to: Create LINQ to SQL Classes Mapped to Tables and Views (O/R Designer)":
The O/R Designer is a simple object relational mapper because it supports only 1:1 mapping relationships. In other words, an entity class can have only a 1:1 mapping relationship with a database table or view. Complex mapping, such as mapping an entity class to multiple tables, is not supported. However, you can map an entity class to a view that joins multiple related tables.
You cannot put more than one object/datasource on a datagrid. You will have to build a single ConceptObject that combines the exposed properties of the part Entities. Try to use DB -> L2S Entities -> ConceptObject. You must be very contrived if the DB model matches the ConceptObject field-for-field.
You are best using a ObjectDataSource when you wnt to do more complex Linq and bind your Grid to the ObjectDataSource.
You do however need to watch out for Anonymous types that could give you some trouble, but anything is posible...

Resources