How do I preserve my custom Linq to SQL class changes? - linq

My MVC2 app use LINQ to SQL as the ORM. I just drag and drop the tables from the SQL Server Explorer connection to the LINQ design surface. Two of the tables (A and B) are related. Table A has 3 foreign keys referencing Table B. In the LINQ design surface, I manually change the name of the parent property for these associations to give them more distinguished names. However, whenever I modify the table structure in the SQL Server, and drag and drop the new structure to LINQ, I would lose the names. Is there a way to prevent this from happening? Thanks.

No. When you drag the tables back to the designer, Linq to SQL regenerates the code in the partial class, obliterating your custom changes.
The only way to preserve the name change is to rename the affected table fields in the database.
You might be able to achieve such customization preservation with the T4 Toolbox.

It is always a bad idea to make the associations at the LINQ level. Make the associations at the table level. This will ensure that when ever you are doing a drag and drop of the tables, the designer class reflects the correct associations.

Related

Visual Studio 2013 Dataset Designer refresh relations

I have an application with a dataset linked to an sql server database. I have updated some of the names or foreign keys and primary keys in the sql server. How do I make those changes translate to the data set. For example, I had a primary key called fk_temsempl_xxxxx. I changed it to fk_temsempl on the sql database. How do I get that change to show in the dataset designer in visual studio?
I have tried running custom tool by right clicking on the dataset and clicking run custom tool. That didnt work. I tried configuring the table adapter of one of the tables where a change occured, but the name of the relation didnt change.
You actually just right click the relation and choose Edit Relation... or double click on the line (when the mouse cursor changes from arrow to drag symbol) but I honestly wouldn't bother; you'll then have further refactoring to do in the code anywhere the relation is used, and it can be heavily used by visual designers.
You also get the problem that VS may not help you with the refactoring: in data binding scenarios most things that can be a source of data can also be a collection of multiple things that can be a valid DataSource. They then rely on a string DataMember to determine which of the collections of data in the data source should be used for the data.
For example, when a bindingsource is bound to list a DataTable, the bindingsource.DataSource property might be the DataSet object that contains the DataTable, and thebindingsource.DataMemberis a string of "YOUR_TABLE_NAME". the BindingSource might not be bound asmyBindignSource.DataSource = myDataSet.MyDataTable`. Refactoring inside strings involves a find and replace
DataRelations in a DataSet are created from foreign keys as they were discovered when the relevant table(s) were added to the dataset but it is important to note that, like DataTables and everything else, they are NOTHING to do with the database schema objects at all - they aren't permanently associated with them, the dataset entities are just set up looking something like the database objects when they (dataset entities) are first created. DataTables are created from only those columns selected, and whatever .NET datatypes closely resemble the types output by the query. For a table of:
Person
------
Name VARCHAR(50)
SSN INTEGER
Birthdate DATE
If you created the table with SELECT * FROM Person you'd get a datatable with Name (string), SSN (int), Birthdate (datetime) but if you made a new datatable in the dataset based on SELECT LEFT(Name, 1) as Initial, PADLEFT(SSN, 20) as PadSSN, DATEDIFF(day, Birthdate, NOW()) as AgeDays FROM Person then you'd get a datatable of Initial (string), PadSSN (string), AgeDays (int) - i.e. the datatable looks nothing like the db table. This concept of disconnection between dataset and db is pervasive, and really the only things that relate in any way to the database are the properties that specify which DB table/column a particular DataTable/DataColumn relates to for purposes of loading/saving data. Your Person.Name datacolumn can be renamed to Blahblah, but it will still have a .SourceColumn property that is set to "Name" - that's how the mapping between dataset and db works; dataset is predominantly completely independent of the db. Renaming a DB column would require a change to the SourceColumn property only
DataRelations don't even have this notion of linking to the parent relation in the database; there's no SourceRelation or SourceFK proeprty because there is no need to. They're set up with the same rules and a generated name all based on the rules of the FK, but then they function independently and only within the dataset. If you rename or even remove an FK from the db the dataset will carry on working in the same restricted way it always did; adding a datarow to a child table when no aprent row exists for it will throw an exception - none of it anything to do with the FK in the db, and the DataRelation can have different rules to the FK (e.g it can cascade deletes when the FK is NOACTION) or even different columns. You can have more or fewer DataRelations than the DB has FKs
Run Custom Tool is not a "contact the DB and see what changes have occurred there and replicate them into the dataset", it is a "turn the XSD that describes the dataset into a bunch of C# classes that implement strongly typed dataset/table/relation/column etc objects". Any time you change the XSD by making an edit in the visual designer and hit save, the custom tool is run. If you edit the XSD directly in a text editor you may need to run it manually to have your changes reflected in c# classes
Reconfiguring a tableadapter probably won't do anything to the relations either; its solely concerned with changing the datatable and tableadapter. If you really want to refresh the relations, delete the datatable from the set and recreate it. Be prepared for a potentially significant mop up/refactoring of code

Issues while generating entities from Views

I am using an Oracle database to generate my EF entities and context.
I do not have control over schema, its all provided by client, and I strictly can't change anything over there.
I have to generate entities for various Views.
When I do this, it is adding all non-nullable columns as the keys (as I can see while opening the edmx in XML editor).
How can I specify which columns should be used as keys? Can I do anything in at EF level without changing the schema?
Ok, I found the solution. We can do this in EF. Select each column in entity, and Set "Entity Key" to "True/ False".

How to update tables from a View using Linq to Entities

I have a View in an SQL Server Database, which involves many different tables. I am using Linq to Entities to access the database, so I have no problem getting and showing view's result.
But the problem is when I want to modify some field in those results. As long as a view doesn't have a primary key, the Entity is read-only, so the question is:
Is there any way to modify the object with the view's data and save those changes in the corresponding tables?
Sorry for my english, but it's not my native language.
Thank you very much in advance!
There are some requirements for VIEW to be updatable. Take a look here. You say your view references many tables, so you have to implement INSTEAD OF trigger.

Cross Database Join with Linq - Updating T4 template to support DB name?

I'm currently running in a multi-DB SQL Server environment and using linq to sql to perform queries.
I'm using the approach documented here to achieve cross DB joins:
http://www.enderminh.com/blog/archive/2009/04/25/2654.aspx
so basically:
2 data contexts - Users and Payments
Users.dbo.UserDetails {PK: UserId }
Payments.dbo.CurrentPaymentMethod { PK: UserId }
I drag the tables onto the DBML, and in the properties window, change the Source from dbo.UserDetails to Users.dbo.UserDetails to fully qualify the DB name.
I can then issue a single data context cross DB join by doing something like:
var results = (from user in datacontext.Table<UserDetail>()
join paymentmethod in dataContext.Table<CurrentPaymentMethod>() on user.UserId equals paymentmethod.UserId
... rest of query here ...);
Now this is tickety boo and works as I want it to. The only problem I'm currently having is when schema updates etc. happen (which is relatively frequent as we're in a significant dev phase).
(and finally, the question!)
What I want to achieve (and I've marked the question up as T4 as a guess, as I know that the DBML files are T4 guided) is an automated way when I drag any table onto a data context that the Source automatically picks up the DB name (so will have Users.dbo.UserDetails instead of just dbo.UserDetails)?
Thanks for any pointers :)
Terry
Have a look at the T4 Toolbox and the LinqToSql code generator it provides (Courtesy of Oleg Sych) - You can customize the templates to generate references however you'd like, but I think the problem you're going to run into is that the database name isn't stored in the dbml file.
What you could probably do is add a filter to the generator, perhaps using a dictionary or similar, such that in your .tt file, you maintain a list of tables and the databases they belong to. That way, if your maintenance task is to delete the class from the designer and drop it on again, it will get the right database 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