Summary of the question: How do i scaffold two or more tables with linq to entities.
I cant find an example; they always scaffold only one table.
Details:
If I have two tables and I use LINQ to entities with a t4 template for dbcontext capability like such:
Table1
Name LastName PositionId
Jose j 1
Table2
PositionPrimaryKey PositionId PositionDescription
1 1 MainProgrammer
If I had these table mapped with linq to entities how would I scaffold them?
Then i put Table1 as my Model class.
I have my employeesentities as dbcontext
But that only creates the values for table 1 and not 2.
If I create a new model that contains both entities, it says is not part of Employeeentities and the class could not be modfied to add my new entity.
So, you have a 1:1 relationship between these tables? If yes, I suggest you creating an entity by hand, set its defining query to the necessary join, and map Insert/Update/Delete to stored procedures in the Mapping Details screen. It involves some (quite simple) sql, but it is the cleanest way for your code above.
If it's not a 1:1 relationship, you need to modify the t4 template to conditionally create the fields of the linked property (it has to navigate the property, and based on some condition, like you say "if property is called Table2", create the extra fields). If you have already done so and it doesn't work, maybe there's something going on with the selection of properties used by MVC scaffolding. It might use reflection and choose only primitive types.
Related
In a data model like this (http://alanstorm.com/2009/img/magento-book/eav.png) I want to get the value from an EAV_Attribute using Linq to SQL.
Assuming that an EAV_Attribute only exists in one inherited table (varchar, decimal, int, etc.) how can I get it in a linq query?
I know that I can use the Inheritance for this, but I want to execute it in the SQL Database side...
Is it possible to do a kind of Coalesce in Linq, considering that the elements have different types?
EAV and linq is not a happy marriage. I think your best shot is to create an unmapped property in eav_attribute that resolves the value (as object) from it's typed attribute child. With entity framework, you won't be able to use this property in an expression (i.e. not in a Where or Select), You must convert to IEnumerable first to access it. (Linq-to-sql may allow it because it can switch to linq-to-objects below the hood).
Another option is to create a calculated column of type sql_variant that does the same, but now in t-sql code. But... EF does not suport sql_variant. You've got to use some trickery to read it.
That's the reading part.
For setting/modifying/deleting values I don't see any shortcuts. You just have to handle the objects as any object graph with parents and children. In sql server you can't use cascaded delete because it can only be defined for one foreign key. (This may tackle that, but I never tried).
So, not really good news, I'm afraid. Maybe good to know that in one project I also work with a database that has an inevitable EAV part. We do it with EF too, but it's not without friction.
First of all, I recommend using TPH and not TPT for EAV tables. (One table with multiple nullable value columns (one per type) + discriminator vs. one table per type.)
Either way, if you modelled the value entity as an abstract class (containing the two IDs) with an inheriting entity per value data type that adds the value property, then your LINQ should look like this:
var valueEntity = context.ProductAttributes.Where(pa =>
pa.ProductId == selectedProductId
&& pa.AttributeTypeId == selectedAttributeTypeId)
.SingleOrDefault() as ProductAttributeOfDouble;
if valueEntity != null
return valueEntity.Value;
return null;
Where the entity types are: Product, AttributeType, ProductAttribute, ProductAttributeOfDouble, ... ProductAttributeOfString.
I am just getting into Entity Framework for the first time beyond simple examples.
I am using the model-first approach and am querying the data source with LINQ-to-Entities.
I have created an entity model that I am exposing as an OData service against a database where I do not control the schema. In my model, I have two entities that are based off of two views in this database. I've created an association between the two entities. Both views have a column with the same name.
I am getting the error:
Ambiguous column name 'columnname'. Could not use view or function 'viewname' because of binding errors.
If I was writing the SQL statement myself, I'd qualify one of the column names with an alias to prevent this issue. EF apparently isn't doing that. How do I fix this, short of changing the view? (which I cannot do) I think this does have something to do with these entities being mapped to views, instead of being mapped to actual tables.
Assuming you can change the model have you tried going into the model and just changing one of the column names? I can still see how it might be problematic if the two views are pulling back the same column from the same table. I can tell that when working directly with a model mapped to tables, having identically named columns is not a problem. Even having multiple associations to the same table is handled correctly, the Navigation Properties are automatically given unique names. Depending on which version of EF you used you should be able to dig into the cs file either under the model or under the t4 template file and see what's going on. Then you can always create a partial class to bend it to your will.
I have three views that I've manually created in the DB.
First view is "Region", the second is "FIPS" and the last is a many-to-many between them called "Region2FIPS". These are all views, and I only need read access the data, so I'm not worried about having updateable views.
I have added each of these views to Entity Framework, and created the appropriate associations between them.
Region to Region2FIPS is a 1 to many.
FIPS to Region2FIPS is a 1 to many.
The "Region2FIPS" view contains only two columns, one called "FIPSID" the other "RegionID". These column are associated with their respective views in the relationships I defined above.
When this type of association is made on tables in the DB, Entity Framework knows that it is a many-to-many relationship and it creates a navigation property on "Region" called "FIPS" that I can use to navigate through the child collection of FIPS. It does likewise for "FIPS" to "Region".
However, when done manually, with views, it does not exhibit that behavior. Instead, my "Region" object has a collection of "Region2FIPS" objects, which each have a navigation property called "FIPS" which is of type "FIPS". And my "FIPS" object has a collection of "Region2FIPS" objects, which each have a navigation property called "Regions" of type "Region".
I assume this has something to do with the fact that I can't create foreign key references on the views, so entity framework doesn't realize the many-to-many relationship. But I thought that if I manually created the many-to-many relationship between the views it would recognize it and properly handle the navigation between the types. Is there a way for me to force it to do this?
It's possible, but the designer doesn't really help you here. You have to do the mapping manually.
One fairly easy way is to use Code First mapping. But this means your model has to be Code First to begin with. If you're writing a new model, just do that.
If you're using DB First mapping, however, you will have to do the mapping manually. Your SSDL will probably already be correct, once you define the "primary keys" of the views. You would then have to remove the "Region2FIPS" objects from the CSDL (not just from the designer!) and manually patch up the MSL.
Perhaps the easiest way to do this would be to use the designer to automatically map real DB tables (not views) with a similar schema and then replace the table names with view names in the EDMX, using the XML editor.
I have three tables Projects, Users and ProjectMembers. The ProjectMembers table is a mapping table and has only two columns ProjectId and UserId.
In my object model i have two classes Project and User. The Project class has a property IEnumerable<User> Members
I am using an external xml map file for mapping linq to sql associations. I am able to get the Project and the User data but I dont know how to map the Members association.
This sounds like a Many-to-Many mapping (Projects <-> Users).
In which case you are going to run into problems using Linq To SQL. To cut a long story short it does not really support that mapping. There are several workarounds which you can find on google, one of which is altering the partial class to provide the access to the Members/Projects collection on the Project and User classes respectively.
e.g. http://www.iaingalloway.com/2015/06/many-to-many-relationships-in-linq-to-sql.html
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...