Hi all,
I’ve neglected the blog for some time because of the projects I’m currently involved in, but I’ll do my best to write more, I promise!
If you make code, you’ve probably at least once had the requirement to save an image in the system. For example, user can upload their profile photo so it could be displayed throughout your application. Let’s see how that could be done in C# ASP.NET, using SQL Server and Entity Framework. Also, we’ll add a cool feature of cropping photos, for which we’ll use jQuery plugin called JCrop. Since this is a fairly long example, I will divide it into couple of posts, first one discussing the database structure.
The database model for this use case is really a basic one. There are three tables: User – where the user information is stored, Image – the same for the photos/images to be uploaded, and UserImage – composite table, containing only primary keys for User and Image tables. Here is the database diagram:
Note: User table structure is taken from a project I work on, so the fields in it reflect that app’s requirements. Some other applications may require different fields. In this example, the only field that will actually be used is UserId. I’ve added only one user to the table, having UserId set to 1. Have this in mind when going through this example!
User:
CREATE TABLE [dbo].[User]( [UserId] [int] IDENTITY(1,1) NOT NULL, [Username] [nvarchar](50) NOT NULL, [Password] [varbinary](32) NULL, [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [Activated] [bit] NULL, [Email] [nvarchar](100) NOT NULL, [Birthday] [datetime] NULL, [GenderId] [int] NULL, [DateCreated] [datetime] NULL, [DateUpdated] [datetime] NULL, [IsDeleted] [tinyint] NULL, CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED ( [UserId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
Image:
CREATE TABLE [dbo].[Image]( [ImageId] [int] IDENTITY(1,1) NOT NULL, [ImageContent] [varbinary](max) NOT NULL, CONSTRAINT [PK_Image] PRIMARY KEY CLUSTERED ( [ImageId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
UserImage:
CREATE TABLE [dbo].[UserImage]( [UserId] [int] NOT NULL, [ImageId] [int] NOT NULL, CONSTRAINT [PK_UserImage] PRIMARY KEY CLUSTERED ( [UserId] ASC, [ImageId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[UserImage] WITH CHECK ADD CONSTRAINT [FK_UserImage_Image] FOREIGN KEY([ImageId]) REFERENCES [dbo].[Image] ([ImageId]) GO ALTER TABLE [dbo].[UserImage] CHECK CONSTRAINT [FK_UserImage_Image] GO ALTER TABLE [dbo].[UserImage] WITH CHECK ADD CONSTRAINT [FK_UserImage_User] FOREIGN KEY([UserId]) REFERENCES [dbo].[User] ([UserId]) GO ALTER TABLE [dbo].[UserImage] CHECK CONSTRAINT [FK_UserImage_User] GO
Here is the corresponding EF model:
Note: If you’re wondering where the UserImage table has disappeared, remember that it is an aggregate table, so in EF model it won’t be represented as entity type, but as association!
In order for this example to be simple, we’ll save only one user to the database and make sure its id is set to 1:
SET IDENTITY_INSERT [User] ON INSERT INTO [User](UserId, Username, Email) VALUES (1, 'test', 'test@example.com') SET IDENTITY_INSERT [User] OFF
When the database is set, we can move on to programming a simple ASP.NET application for saving the images. You can check how it is done in this post.