Globalization of Database Stored Values - c#

We are using resource files (.resx) to translate our .NET 4.5 MVC C# application to different languages. This works great for static text that is located in our views. However, we have values that are pulled from our SQL database that need to be translated as well.
An example: Dropdown list with values that are populated from a table in the database.
What is the best practice for translating these values in the database?

The last multilingual application I designed I've used a table for language, and for each table that had any string types (char, varchar etc`) I had a translation table.
Something along these lines:
CREATE TABLE TblLanguage
(
Language_Id int identity(1,1) PRIMARY KEY,
Language_EnglishName varchar(30),
Language_NativeName nvarchar(30),
CONSTRAINT UC_TblLanguage UNIQUE(Language_EnglishName)
)
CREATE TABLE TblSomeData (
SomeData_Id int identity(1,1) PRIMARY KEY,
SomeData_TextColumn varchar(50),
....
)
CREATE TABLE TblSomeData_T ( -- _T stands for translation
SomeData_T_SomeData_Id int FOREIGN KEY TblSomeData(SomeData_Id),
SomeData_T_Language_Id int FOREIGN KEY TblLanguage (Language_Id),
SomeData_T_TextColumn nvarchar(100),
PRIMARY KEY (SomeData_T_SomeData_Id , SomeData_T_Language_Id)
)
My application had English as it's default (or main) language, so I kept the default language in the base table and only the translations on the translation tables. You could, of course, keep the string values only in the translations table if you want to. Note that this does not take into consideration the different date and number formats for each culture, this is done on the presentation layer.

Related

Microsoft Sync Framework unique index error

I use the MS Sync Framework to sync my SQL Server instance with a local SQL CE file to make it possible working offline with my Windows app.
I use GUIDs as keys. On my table I have a unique index on 2 columns: user_id and setting_id:
usersettings table
------------------
id PK -> I also tried it without this column. Same result
user_id FK
setting_id FK
value
Now I do the following:
I create a new record in this table in both databases - SQL Server and SQL CE with the same user_id and setting_id.
This should work and merge the data together since this can happen in real life. But I get an error when syncing saying the unique key constraint led to an error. The key pair already exists in the table.
A duplicate value cannot be inserted into a unique index. [ Table name = user_settings,Constraint name = unique_userid_settingid ]
Why can't MS sync handle that? It should not try to insert the key pair again. It should update the value if needed.
The issue is if you add the same key pair to different copies of the table, they get different IDs (GUIDs) as primary keys in this usersettings table.
As this is simply a many-to-many table between Users and Settings, there is no need to have that ID as a PK (or even a column at all).
Instead, just use a concatenated key of the two FKs e.g.,
CREATE TABLE [dbo].[usersettings](
[user_id] [UNIQUEIDENTIFIER] NOT NULL,
[setting_id] [UNIQUEIDENTIFIER] NOT NULL,
[value] [varchar](50) NOT NULL,
CONSTRAINT [PK_usersettings] PRIMARY KEY CLUSTERED ([user_id] ASC, [setting_id] ASC) );
Of course, include appropriate field settings (e.g., if you use VARCHARs to store the IDs) and relevant FKs.
As the rows inserted should now be identical on the two copies, it should merge fine.
If you must have a single column as a unique identifier for the table, you could make it meaningful e.g.,
the PK (ID) becomes a varchar (72)
it gets filled with CONCAT(user_ID, setting_id)
As the User_ID and Setting_ID are FKs, you should already have them generated so concatenating them should be easy enough.
Do you get the error during sync, then it should appear as a conflict, that you must solve in code.
https://learn.microsoft.com/en-us/previous-versions/sql/synchronization/sync-framework-2.0/bb734542(v=sql.105)
I also see this in the manual: By default, the following objects are not copied to the client database: FOREIGN KEY constraints, UNIQUE constraints, DEFAULT constraints, and the SQL Server ROWGUIDCOL property. This indicates poor support for your scenario
I suggest you remove the unique constraint from the device table.

MySqlException was unhandled error trying to create relational database

I get this error when i am trying to create a relational database:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' REFERENCES classes(Name))' at line 1
I used a Update method to update the data base and create new tables, the first Update method works but then the second one breaks it. This is my code
one.Update("CREATE TABLE classes (Name VARCHAR (30) , Primitive1 VARCHAR(30), Primitive2 VARCHAR(30), Primitive3 VARCHAR(30), PRIMARY KEY(Name)) ");
one.Update("CREATE TABLE primitives (Name VARCHAR(30), Size_bytes INT, Description TEXT, FOREIGN KEY (Classes), REFERENCES classes(Name))" );
You may have other problems, but you have an extra comma in the foreign key statement:
FOREIGN KEY (Classes), REFERENCES classes(Name)
should be:
FOREIGN KEY (Classes) REFERENCES classes(Name)
I note that you have no actual column called Classes in the table. Either you need to declare that, or you might mean:
FOREIGN KEY (Name) REFERENCES classes(Name)
EDIT:
And I'm a strong advocate of auto incrementing keys:
CREATE TABLE classes (
ClassesId int auto_increment primary key,
Name VARCHAR(30) not null unique,
Primitive1 VARCHAR(30),
Primitive2 VARCHAR(30),
Primitive3 VARCHAR(30)
);
CREATE TABLE primitives(
PrimitivesId int auto_increment primary key,
Name VARCHAR(30),
Size_bytes INT,
Description TEXT,
ClassId int references classes(ClassId)
);
Note the use of inline references. I'm sure some will disagree, but I find it easier to follow column definitions when they are in one place. Also, this adds auto-incrementing primary keys and uses the same column name for the primary key and foreign key.
Finally, having three columns that look the same -- Primitive1, Primitive2, and Primitive3 -- is usually a poor design. It is better to have another table with one row per class and "Primitive".
one.Update("CREATE TABLE primitives (Name VARCHAR(30), Size_bytes INT, Description TEXT, FOREIGN KEY (Classes) REFERENCES classes(Name))" );
is correct. You had comma , before REFERENCES

How to solve bad database design with Entity Framework?

I apologize for the strange question; it is hard to put into words. I am forced to work with a database of questionable design and I would like to solve data access issues with the Entity Framework. I am at a loss how to treat this type of design in an object oriented way.
The Item table is the problem. It has fields that may contain different types of data, ranging from Size to Lot Numbers to SO numbers, etc. The name of the field is determined by the ItemDef table, which links to a ItemDefValue table with the actual field names. The tables have been simplified for demonstration purposes.
Create Table Item
(
ItemKey int Primary Key not null,
ItemID1 varchar(100) null,
ItemID2 varchar(100) null,
ItemID3 varchar(100) null,
ItemID4 varchar(100) null,
ItemDefKey int not null --foreign key to ItemDef table
);
Create Table ItemDef
(
ItemDefKey int Primary Key not null,
CustomerKey int not null , -- foreign key to cusotmer table
);
Create Table ItemDefValue
(
FieldCode small not null,
Title varchar(50) not null
ItemDefKey int not null - foreign key to ItemDef table
);
I have solved this problem with DataSets and DataTables by renaming columns based on the ItemDefValue, so I am not looking for a table-based solution. I would like to avoid this type of table-based logic, especially since I am not fond of DataSets and would rather accomplish data access using the Entity Framework.
I would appreciate advise from anyone that has dealt with this kind of problem before. I would specifically like any suggestions on how to treat this kind of database design in an object oriented way, preferably using the Entity Framework.
And if you think there is no other solution than to re-design the database than I will take that advise as well.
Thanks.
Messy! A restructure would definitely be best.
But, how about creating views that represent the way you'd like the tables to be organised at an object level - and then with EF use those views rather than the tables directly. You'd need to function map the insert/update/delete to stored procedures for dealing with the real tables, but at least from EF side of things you'd be dealing with a decently organised set of entities rather than those tables ...

SQL: Associate a single type with multiple records of various other types

Designing a database with many tables and want to add a general Note table. I want a Note object to be able to attach to several other tables. So one Note can be associated with a particular Contact, maybe a Job, and also a few different Equipment objects. I'd like to be able to filter Note objects by the particular objects they are associated with.
Well, here's one way:
CREATE TABLE NoteTables
(
TableID INT NOT NULL Identity(1,1),
TableName SysName NOT NULL,
CONSTRAINT PK_NoteTables PRIMARY KEY CLUSTERED(TableID)
)
GO
CREATE TABLE TableNotes
(
TableID INT NOT NULL,
RowID INT NOT NULL,
NoteID INT NOT NULL,
CONSTRAINT PK_NoteAttachments PRIMARY KEY CLUSTERED(TableID, RowID, NoteID)
)
GO
CREATE TABLE Notes
(
NoteID INT NOT NULL Identity(1,1),
Note NVARCHAR(MAX),
CONSTRAINT PK_Notes PRIMARY KEY CLUSTERED(NoteID)
)
Note that I am assuming SQL Server and the use of IDENTITY columns here (if Oracle, you can use Sequences instead).
The Notes table contains all of the notes and gives them an ID to use as both a referemce and a primary key.
The NoteTables just list all of the tables that can have note attached to their rows.
TableNotes links the notes to the tables and rows that they are attached to. Note that this design assumes that all of these tables have INT ID columns that can be used for unique referencing.
It would take you two tables. Structure is as easy as the following.
Note table:
NotePK | tableFK | note
And a table that lists all your tables.
Either you create one (then you have full control but need to maintain it) or you take the
sys.tables t
You read it out by SELECT * FROM sys.tables t
the column object_id would be your tableFK in the first table
You can store as many comments as you like. If you want to get the note simply query the note table and filter for your tableFK.

C# with SQLite and foreign key

I want to implement a patients data base for our software, and have an issue with the foreign key statement. I am using the latest SQLite DLLs, with C#.
When I try to run below code:
dbConnection = "Data Source=SQLiteMyDatabase.db;foreign keys=true;";
if (connections == 0)
{
cnn = new SQLiteConnection(dbConnection);
cnn.Open();
this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS patients ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(100) NOT NULL;");
this.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS images ( FOREIGN KEY (patientID) REFERENCES patients(id), nameRed VARCHAR(20) NOT NULL PRIMARY KEY;");
}
I get the error:
SQLite error near "FOREIGN": syntax error
Why does this happen?
In order to create a foreign key, you must first create the column:
CREATE TABLE IF NOT EXISTS images (
nameRed VARCHAR(20) NOT NULL PRIMARY KEY,
patientID INT,
FOREIGN KEY (patientID) REFERENCES patients(id)
);
Please note:
I moved the primary key column (nameRed) first in the list of columns created, but that's just convention. It could go second.
You use the data type VARCHAR and SQlite will accept that, but be aware that it gets mapped to type TEXT, the maximum length will be ignored, and you will be able to store other data types in the column. SQLite is a bit funny when it comes to data types (it has a very well thought-out system but it's quite different from most other SQL databases).
To make things more confusing, you are allowed to declare the PRIMARY KEY as a property of the column (although you can also do it after the list of columns as with the FOREIGN KEY).

Categories

Resources