GUID of 00000000-0000-0000-0000-000000000000 causing merge index violation - sql-server-2008

Our developer has a linq-2-sql project that talks to my database. The database is involved in merge replication. It has been in use for some time and was working fine. A recent table was added to the schema and now is causing problems when new records are added.
The user get's an error message stating that the index related to the guid that merge replication automatically creates is violating a unique constraint.
From what I can tell the table isn't any different than others that are involved. I have recreated the entire replication publication/subscription model from scratch and everything continues to work but that one table.
Anyone have any ideas? The guid being created appears as 00000000-0000-0000-0000-000000000000 which would explain why it's a duplicate. Why is a valid guid not being created by linq?

Did you use "new Guid()" somewhere in your code base when what you meant was "Guid.NewGuid()"?

I had faced the similar problem. As Mark has mentioned in the comment, the Guid() needs to be properly used.
Guid asm = new Guid(); // gives 00000000-0000-0000-0000-000000000000
Instead use
Guid asm = Guid.NewGuid();

When using Linq-To-SQL, make sure the IsDbGenerated property is true and the Database actually is setup to create an ID (by using newid() as the default value).
Otherwise, make sure the .net code is actually generating IDs.

What we discovered while researching your suggestions was that this particular table was the only table that included the guid field at all in the DBML class. All the other tables had been added to the DBML prior to publishing the database for merge replication (hence their respective guid fields were not included in the DBML).
So, I manually deleted the guid field from the problem table in the DBML and the problem went away. The problem was in fact caused by LINQ not creating the guid as it should in the generated classes.
In this case it was easiest to simply leave guid creation to the publication triggers and newid() default value as established in SQL. (it's still in the database, just not the dbml)
Nothing in the application uses those guid fields... it's purely for SQL to manage the merge replication scheme we've implemented - so removing from the DBML was the easiest.

Related

If I update a SQL table Scheme. Do I have to update all users DBs linked tables?

I updated the SCHEMA of a live table in MySQL for use in my multi-user database. Each user has their own db and links to the production tables through ODBC.
I have been receiving a write error while trying to test my schema updates. I cannot find the core reason. I hypothesized that because the other users are in the production table but have not been relinked to update the table SCHEMA; That it is causing a conflicting write error on my relinked table.
I added a TINYINT with No NULLS and default value of 0
I double checked all datatypes for incompatibility & have tested the "non relinked" tables in a older version of the DB and confirmed it is working as intended with no errors
I expect/want to be able to edit records without a write error, but am hesitant to update the other users to the new table if it is currently having write errors
After changing the schema of a linked table, it's required to refresh the link on all Access databases connected to it.
You can do this on the ribbon through external data -> linked table manager.
Unfortunately, either all users that have a database need to do this manually, unless you automate the task on startup through vba.
You have two separate issues. To "see" new columns, then yes, you must re-link the tables.
(so above is separate question and separate issue). You thus as a general rule can add new columns to the database (even while in use). However, the client side linked tables will not see the new columns until such time you re-link. This approach (adding new columns, but not yet re-linked from Access) is certainly ok and fine - the only downside is end users can't see nor use the new columns until such time you link. From a developer point of view, this good - since your users will not see nor find new columns until such time you roll out a new front end to each work station.
Ok, now problem and issue number two.
As for adding a new column, then re-linking, and THEN having some issue is really a separate issue. In most cases, if you attempting to use a tiny int as a Boolean (and I think that is your case), then you need to ensure several things:
Do not allow nulls (you seem to have this ok).
Make sure you set a default of 0 (server side) for this column. (you might have not allowed nulls, but without a default, then Access likely will still complain. And this default is important during creating time - since the new column needs to be "filled" with zeros.
Make sure the table has a PK defined.
Consider adding a row version column (I think mySQL has these, not sure but they can help immensely).

Add a global rule to modify dates for all database inserts & updates

I have a requirement to add a rule to a legacy MySQL 5.1.73 database whenever a specified date is about to be inserted or updated into any of the tables. (Each field already had a default date setting so using that in some way is not a viable solution).
For example:
IF NewDate = *TheSpecifiedDate* THEN SET NewDate = *ConstantDate*
The logic for this will be identical for all tables that have one or more DateTime fields.
My only solution at the moment is manually add triggers to each and every table. This will be a lot of work to do, and a lot of hassle to maintain if the requirement ever changes.
I therefore wondered if I can somehow make this a globalized rule/trigger for the entire database whenever an insert or update is attempted on any DateTime field?
Or is there a more elegant/preferred way of implementing this kind of global rule that may not even involve using triggers?
Just to close this off, for anyone trying to do something similar...
The main restriction in my scenario was that I am slowly migrating 200+ legacy applications and could therefore not manipulate the legacy database behavior or structure until all applications are converted. I also needed to replicate some existing behavior, whether I liked it or not!
When I posted this question I was using EF6 for my data access layer. Having changed to EF Core 1.1.0 I can now utilise the 'HasDefaultValueSql' setting in my table mappings which resolves my particular issue by allowing me to set a value whenever the DB is updated.

Linq to SQL: Removal of column from DB and code causes invalid column error

I have a very very simple implementation of linq to sql in a sharepoint 2010 service application, but ran into a bit of a roadblock.
There are no generated classes, im just using a System.Data.Linq.Mapping statement, a [Table(Name="")] tag in the class and the columns with a [Column(Name="")] tag. And in the context object I made, it extends the DataContext class, and has a Table<> object. Nothing more.
Yesterday I was asked to remove a column from the DB (fairly late in implementation) but it was a simple job. I deleted the column from the db, removed the object from the class and went through all of my affected code to remove references to this old column.
However, I am getting an Invalid Column Error whenever the linq to sql object for that table is used.
I have deleted the table and recreated it, cleaned my VS solution, rebuilt it, re checked it out from our repo, deleted all generated objects from the file system and have yet to fix this.
Does anyone have an idea of how to fix it?

Entity Framework 4.1 Custom Database Initializer strategy

I would like to implement a custom database initialization strategy so that I can:
generate the database if not exists
if model change create only new tables
if model change create only new fields without dropping the table and losing the data.
Thanks in advance
You need to implement IDatabaseInitializer interface.
Eg
public class MyInitializer : IDatabaseInitializer<MyDbContext>
{
public void InitializeDatabase(MyDbContext context)
{
//your logic here
}
}
And then set your initializer at your application startup
Database.SetInitializer<ProductCatalog>(new MyInitializer());
Here's an example
You will have to manually execute commands to alter the database.
context.ObjectContext.ExecuteStoreCommand("ALTER TABLE dbo.MyTable ADD NewColumn VARCHAR(20) NULL");
You can use a tool like SQL Compare to script changes.
There is a reason why this doesn't exist yet. It is very complex and moreover IDatabaseInitializer interface is not very prepared for such that (there is no way to make such initialization database agnostic). Your question is "too broad" to be answered to your satisfaction. With your reaction to #Eranga's correct answer you simply expect that somebody will tell you step by step how to do that but we will not - that would mean we will write the initializer for you.
What you need to do what you want?
You must have very good knowledge of SQL Server. You must know how does SQL server store information about database, tables, columns and relations = you must understand sys views and you must know how to query them to get data about current database structure.
You must have very good knowledge of EF. You must know how does EF store mapping information. You must be able to explore metadata get information about expected tables, columns and relations.
Once you have old database description and new database description you must be able to write a code which will correctly explore changes and create SQL DDL commands for changing your database. Even this look like the simplest part of the whole process this is actually the hardest one because there are many other internal rules in SQL server which cannot be violated by your commands. Sometimes you really need to drop table to make your changes and if you don't want to lose data you must first push them to temporary table and after recreating table you must push them back. Sometimes you are doing changes in constraints which can require temporarily turning constrains off, etc. There is good reason why tools which do this on SQL level (comparing two databases) are probably all commercial.
Even ADO.NET team doesn't implemented this and they will not implement it in the future. Instead they are working on something called migrations.
Edit:
That is true that ObjectContext can return you script for database creation - that is exactly what default initializers are using. But how it could help you? Are you going to parse that script to see what changed? Are you going to execute that script in another connection to use the same code as for current database to see its structure?
Yes you can create a new database, move data from the old database to a new one, delete the old one and rename a new one but that is the most stupid solution you can ever imagine and no database administrator will ever allow that. Even this solution still requires analysis of changes to create correct data transfer scripts.
Automatic upgrade is a wrong way. You should always prepare upgrade script manually with help of some tools, test it and after that execute it manually or as part of some installation script / package. You must also backup your database before you are going to do any changes.
The best way to achieve this is probably with migrations:
http://nuget.org/List/Packages/EntityFramework.SqlMigrations
Good blog posts here and here.

SqlDateTime overflow on INSERT when date is correct using a Linq to SQL DataContext

I get an SqlDateTime overflow error (Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.) when doing an INSERT using an Linq DataContext connected to SQL Server database when I do the SubmitChanges().
When I use the debugger the date value is correct. Even if I temporary update the code to set the date value to DateTime.Now it will not do the insert.
Did anybody found a work-around for this behaviour? Maybe there is a way to check what SQL the datacontext submits to the database.
Do you have the field set as autogenerated in the designer? If that's not the problem, I'd suggest setting up logging of the data context actions to the console and checking the actual SQL generated to make sure that it's inserting that column, then trace backward to find the problem.
context.Log = Console.Out;
FWIW, I often set my "CreatedTime" and "LastUpdatedTime" columns up as autogenerated (and readonly) in the designer and give them a suitable default or use a DB trigger to set the value on insert or update. When you set it up as autogenerated, it won't include it in the insert/update even if modified. If the column doesn't allow nulls, then you need to supply an alternate means of setting the value, thus the default constraint and/or trigger.
Are you sure you're looking at the right Date column? Happened to me once, and the error turned out to be caused by another non-nullable Date column that wasn't set before submitting.
I came across this recently.
The error may as well say "something's preventing the save!". Because in my case, it was not the DateTime value that was the problem.
I thought I was passing a value in for the primary key, and what was arriving was "null". Being the key, it can't be null - and so my problem was completely somewhere else. By resolving the null, the problem disappeared.
We all hate misleading errors - and this is one of them.
Lastly, as a suggestion... If you do find conversion of dates a problem, then don't use dates at all! .NET's DateTime class supports the "Ticks" value. It can also instantiate a new DateTime(ticks); too. The only Gotcha with that one, is the implementation of ticks in Javascript has a different starting point in history. So you might want a conversion between ticks if you ever tried getting DateTimes from c# to Javascript.
I suggest you change your project's Target Framework. Maybe SQL Server is newer than .Net Framework. I see the same your issue:
My project's Target Framework is 3.5.
SQL Server is 2012
And then I change to 4.0. The issue is solved.
Bottom line: watch the order of your calls to SubmitChanges() and ensure that all objects that would be "submitted" are actually ready to be submitted. This often happens to me when I'm in the middle of setting the attributes of new LINQ object (e.g, the ".FirstName" of new "tblContact"), and then some conditional logic requires the creation of a separate, related record (e.g., a new "tblAddress" record), so the code goes to create the "tblAddress" and tries to SubmitChanges() on saving that record, but that SubmitChanges() then also tries to insert the unfinished "tblContact" record, which maybe doesn't yet have a required "BirthDate" field value set. Thus, the exception looks to occur when I'm inserting the "tblAddress" object/record, but actually refers to the lack of "BirthDate" for the "tblContact" object/record.