We had developed in the past some sites, from company presentation sites to eshops, in classic asp. All of these was developed in multilingual environment (el, en) most of them. From database view we had choose the following schema. For example, for products table we have two related tables one with no lingual depended fields and one for lingual depended fields with one to many relation.
CREATE TABLE ref_language (
Code Char(2)NOT NULL,
Name Varchar(20) NOT NULL,
PRIMARY KEY (Code)
);
CREATE TABLE app_product (
Id Int IDENTITY NOT NULL,
PRIMARY KEY (Id)
);
CREATE TABLE app_product_translation (
ProductId Int NOT NULL,
LanguageCode Char(2) NOT NULL,
Description Text NOT NULL,
FOREIGN KEY (ProductId) REFERENCES app_product(Id),
FOREIGN KEY (LanguageCode) REFERENCES ref_language(Code)
);
To recreate the product model we use stored procedures to join the two tables for the requested language.
Now we want to move into dot.net mvc model. And we are wondering if there is a better approach, most suitable in mvc model.
It depends on your requirements, but you can just create a class to load and cache the captions in memory, loading them using EF. Either use a static class or preferably the ASP.NET cache.
If you are doing dynamic stuff on the client side then expose the strings through a MVC of WebAPI controller if necessary.
To make this easier I would decouple your translations from products in the schema. Make your translations universal.
Just have a single table called app_translation with Id, LanguageCode and Translation field. Then reference the Id on any table that needs a translated caption.
To enforce referential integrity, you can also have a app_translation_identifier table with a single column and a unique constraint. Then FK from the app_translation.Id to app_tranlsation_identifier.Id. And also have a unique key on app_translation for the Id and LanguageCode.
Related
I have some problems working with model first many to many relationship. Since I created many-many relationship between Town and Author via interface builder it created table TownAuthor with keys Towns_TownID and Authors_AuthorID but I want that just to be called TownID and AuthorID, how do I change that?
In Code first I would use that modelBuilder configuration in Context but I have no idea how to do this via model first...
You have to change the names of these columns in the Entity Designer DDL script (which is generated from the EDMX file and has ModelName.edmx.sql name) before executing it.
-- Creating table 'TownAuthor'
CREATE TABLE [dbo].[TownAuthor] (
[TownID] int NOT NULL,
[AuthorID] int NOT NULL
);
GO
Today I read about the new features in ASP.NET Identity 2.0 alpha.
http://blogs.msdn.com/b/webdev/archive/2013/12/20/announcing-preview-of-microsoft-aspnet-identity-2-0-0-alpha1.aspx
Apparently the possibility to use and int or a guid as the primary key for the AspNetUsers table was added after numerous post/questions on stackoverflow.
I started using ASP.NET Identity when the RTM was announced. Since then I have been using the default string (nvarchar(128)) type for the Id column in the AspNetUsers table.
I want my app to be futureproof. So what I'm wordering is wheather or not I should follow the instructions in these new documents on how to change your Id column to and int or a guid.
What is the most appropriate for an e-commerce site?
What is the most appropriate for a regular site?
When to use what?
Update 1:
Already found one good thing about using an int while testing PrimaryKeysConfigTest WebForms sample app (https://aspnet.codeplex.com/SourceControl/latest Samples->Identity->ChangePK->PrimaryKeysConfigTest). When updating the table AspNetUserRoles manually in SQL Server Object Explorer you don't need to copy paste the long guid-string into the UserId and RoleId columns. You remember them by heart.
Update 2:
https://aspnet.codeplex.com/SourceControl/latest Samples->Identity->Identity-PasswordPolicy->Identity-PasswordPolicy is an MVC application and uses a nvarchar(128) for the Id column in AspNetUsers table. If you're looking to implement the new user account confirmation/forgot password features in ASP.NET Identity 2.0 alpha for an MVC application then this is the sample app you should look at.
I'm newbie to Yii. Official documentation does not give any examples for CDbMessageSource.
Questions:
1) How/Where do I set CDbMessageSource as my MessageSource ?
2) In my current application I store Categories in one table and translations for Categories in other table. Tables structure:
CATEGORY
----------
cat_id (PK)
CATEGORY_TRANSLATION
--------------------
cat_id (FK)
en
ru
Now if I introduce sub-categories I would model DB this way:
SUB_CATEGORY
------------
sub_cat_id (PK)
cat_id (FK)
SUB_CATEGORY_TRANSLATION
------------------------
sub_cat_id (FK)
en
ru
Do I understand it correctly that in Yii if I want to use CDbMessageSource to store translations then I would need to merge CATEGORY & SUB_CATEGORY in to one table , then merge CATEGORY_TRANSLATION & SUB_CATEGORY_TRANSLATION in to other so that in result I get following structure (taken from here http://www.yiiframework.com/doc/api/1.1/CDbMessageSource) :
CREATE TABLE SourceMessage
(
id INTEGER PRIMARY KEY,
category VARCHAR(32),
message TEXT
);
CREATE TABLE Message
(
id INTEGER,
language VARCHAR(16),
translation TEXT,
PRIMARY KEY (id, language),
CONSTRAINT FK_Message_SourceMessage FOREIGN KEY (id)
REFERENCES SourceMessage (id) ON DELETE CASCADE ON UPDATE RESTRICT
);
Thank you !
How to enable CDbMessageSource
The message source is an application component with the name "messages". Therefore you configure it just like any other component in your application configuration file:
array(
......
'components'=>array(
......
'messages'=>array(
'class'=>'CDbMessageSource',
// additional parameters for CDbMessageSource here
),
),
),
)
The message source and localizable models -- not an ideal relationship
It's important to keep in mind that the message source only provides translations for known messages. It does not make much sense to involve the message source in your model localization because how would you utilize it?
Assume you have a category with id = 1. How would you get its localized title? Something like Yii::t('category', 'title_'.$category->id) could work, but it's somewhat clumsy (not desirable syntax, you have to "bake in" your primary key information into your display code, etc). If your title localizations are also meant to be modifiable by users this is going to get even more complicated. (In any case, if you wanted to do this then merging the two translation tables and using a separate value when populating SourceMessage.category would be the way to go).
An alternative approach to localizing models
Here's a brief rundown of how you can conveniently localize your models. Let's say we have a Room model with a localizable name property. You can create a new table named LocalizedString and the corresponding model that has a structure similar to this:
CREATE TABLE IF NOT EXISTS `localized_string` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`LocaleCode` char(5) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`StringTemplate` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`Id`,`LocaleCode`),
);
Then, configure your Room model with a relation on LocalizedString:
public function relations()
{
$localeCode = Yii::app()->getLanguage();
return array(
'nameStringTemplate' => array(
self::BELONGS_TO, 'LocalizedString', 'NameStringTemplateId',
'condition' => 'nameStringTemplate.LocaleCode = \''.$localeCode.'\''),
);
}
And add a read-only property:
public function getName() {
return $this->nameStringTemplate->StringTemplate;
}
By doing this, you can now write $room->name anywhere and you will automagically get back the localized translation for the application's current language.
There are many details that need to be taken care of and that I have glossed over here, but the idea should be apparent.
I am making an application using MVC 3.0 Razor and Code First Entity Framework.
I am wondering how to define primary key and Foreign Key Relation in the Model.
I know how to define Primary Key.using Key attribute.
for example, I define [Key] attribute in the Model Table Class for Primary Key.
But, really don't know how to define Foreign Key for column in class.
Please Help..................
You can just make a List<ChildType> property in the parent class and a ParentType property in the parent class.
EF will generate the key automatically.
I have a modeling question related to profiles. Firstly, I have looked into using the SQLTableProvider and using the in built profiling system but didn't feel they were suitable. So, with that said, I have a membership scheme where every person has a profile, then that person can upgrade their profile to either an individual (additional fields) or a company account (additional fields again).
So I thought, use a Profile base class and then inherit from that for the Company account and Individual account. However, when it comes to implementing this in MVC I'm hitting a brick wall.
Since either the company or individual edit pages are effectively updating both the base Profile table and also the individual/company tables from the same page. How would I go about implementing this within the model (which is currently generated via LinqToSQL) and also at the view level?
Apologies if that wasn't very clear, tricky one to explain!
If you are using Linq to SQL, then you already have a model. Linq generates the entities and collections based on your database for you. The generated model is a shallow one, but is pretty solid and workable. The Linq to SQL model can be extended via partial classes allowing you to enhance entities or the context itself for additional functionality.
The controller can work directly against the generated model and pass entities or collections of entities to the view as needed.
I would suggest that, for what you appear to be trying to do, you might consider not using the built-in profile provider system at all. The profile providers in asp.net work well for simple personalization stuff, but it doesn't work well for concrete data like contact info and such. Also keep in mind that the profile provider systems tend to store object data as serialized strings in the database... this makes getting at profile data very difficult from admin tools and such. Performance starts to become a problem VERY fast in any case where you are needing multiple user's profile information (such as with an admin user editor).
For a when you are storing important personal details like the stuff you mentioned, what you are really storing are "account details" not "user profiles". You can extend a membership provider to expose your additional details, but I've generally found it much easier to just roll my own data model and access logic to deal with the additional account information.
My rule of thumb is this: if the information is ONLY needed during a request made by the user to whome the data belongs, then it goes in profiles. If I would need the data for one user to be read during another user's request, or if I would need a "list" of that data for different users, then it doesn't go in asp.net profiles.
Do you mean settings like choosing how many items to view on each page, and choosing some style sheet?
public class Profile
{
int? ItemsPerPage { get; set; }
string PreferredStyleSheet { get; set; }
}
The company selects some values that will work for users unless the users have chosen some other values for themselves. Is that what you have in mind?
In that case: I don't know how to do it together in ASP.NET Profile, but how about the following tables in the database:
TABLE Setting
(
SettingID int NOT NULL,
SettingName varchar(32) NOT NULL,
DefaultValue nvarchar(128) NULL
)
TABLE CompanySetting
(
CompanySettingID int NOT NULL,
RefSettingID int NOT NULL,
RefCompanyID int NOT NULL,
SettingValue nvarchar(128) NOT NULL
)
TABLE UserSetting
(
UserSettingID int NOT NULL,
RefSettingID int NOT NULL,
RefUserId uniqueidentifier NOT NULL,
SettingValue nvarchar(128) NOT NULL
)
And then make some joins for the present user. If the user setting is not given, take the company setting; if the company setting is not given, take the default value.