How can i create layered struct in asp.net - c#

I'm learning C# & ASP.NET.
I'm trying to make a struct, I don't know is it ok call it ORM.
I have a database (using Entity Framework), and I try to separate SQL queries from aspx's codebehinds.
I've got 4 tables in my database (Kitaplar,Musteriler,Kiralamalar,Turler)
in my Kitaplar table I have got 8 field (KitapID(FK),KitapAdi,ISBN,Yayinevi,Yazaradi,Basimtarihi,Stok,TurTurID).
I created a class Kitapmodel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace KütüphaneYonetimSistemi.Models
{
public class KitapModel
{
public int KitapID { get; set; }
public string KitapAdı { get; set; }
public string ISBN { get; set; }
public string Yayınevi { get; set; }
public string YazarAdı { get; set; }
public DateTime BasimTarihi { get; set; }
public int Stok { get; set; }
public int TurTurID { get; set; }
}
}
I also created kitapModelProvider.cs for database connection and other things At this is the point I'm stuck.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace KütüphaneYonetimSistemi.Providers
{
public class kitapModelProvider
{
}
public KitapModel getByKitapID(int ID)
{
KutuphaneYonetimDB db = new KutuphaneYonetimDB();
KitapModel bookListEF = from k in db.Kitaplar
join t in db.Turler
on k.TurTurID equals t.TurID
select new
{
k.KitapAdı,
k.YazarAdı,
t.TurAdı,
k.Yayınevi,
BasimTarihi = k.BasimTarihi.ToString().Replace(" 12:00AM", "").Replace("Jan", "Ocak").Replace("Feb", "Şubat").Replace("Mar", "Mart").Replace("Jun", "Haziran").Replace("Sep", "Eylül").Replace("Nov", "Kasım").Replace("Oct", "Aralık").Replace("Apr","Nisan"),
k.ISBN,
k.Stok
};
return bookListEF;
}
public void insertKitap(KitapModel kitap)
{
KutuphaneYonetimDB db = new KutuphaneYonetimDB();
db.Kitaplar.Add(kitap);
db.SaveChanges();
}
/*
other methods
*/
}
And in my createBook.aspx.cs file I want to do something like this;
KitapModel kitap = new Kitapmodel {
kitapAdi = "Harry Potter ve Felsefe Taşı",
ISBN = ......
Yayınevi....
...
Stok = 5,
TurTurID = 1 }
kitapModelProvider.insertKitap(kitap) // or kitapModel.insertKitap

Okay since you are new to programming on ASP.NET, I try to put you on a right path.
First What is an ORM :
From wikipedia:
Object-relational mapping (ORM, O/RM,
and O/R mapping) in computer software
is a programming technique for
converting data between incompatible
type systems in relational databases
and object-oriented programming
languages. This creates, in effect, a
"virtual object database" that can be
used from within the programming
language. There are both free and
commercial packages available that
perform object-relational mapping,
although some programmers opt to
create their own ORM tools.
It's good for abstracting the data-store (SQL Databases / NoSQL Databases and so on) out in order to provide an interface that can be used in your code. Commonly used ORMs within .NET for Connecting to SQL are:
ADO.NET
LINQ To SQL
ADO.NET Entity Framework
Now You've choosen EF (Entity Framework) as Object-relational mapping [ORM]. Second Step would be learning basics of EF Which you can Find here.
EF Provides 2 type of approaches:
Code-First
Where you would provide the POCO classes and their mapping And EF would create the table designs for you within the dbcontext class's OnBuildingMethod().
Database-First
Traditional way to create table designs then you connect your database to your application and add a ADO.NET Entity Data Model and using it's wizard you call all of your tables and create their POCOs for you.
After You've learned About these and how it does work, you need to know about The EF CRUD Operations.
And in the end you can start look at Repository Pattern And Unit of Work Pattern using EF.

Related

Read and Write to database with generic DataTable using Entity Framework

Is it possible to read and write to a SQL Server database using DataTable with Entity Framework?
I have multiple code tables defined in my database such that each of them share a fixed set of properties as shown in the sample below.
For example
public class CTGender
{
public Guid ID { get; set; }
public string Description { get; set; }
public string DisplayValue { get; set; }
//...Other properties specific to CTGender
}
public class CTNationality
{
public Guid ID { get; set; }
public string Description { get; set; }
public string DisplayValue { get; set; }
//...Other properties specific to CTNationality
}
The situation I face right now is the ever expansion of my code tables, could be another CTCountry, CTRole and so on, for example.
I am trying to synchronise these code tables between multiple databases.
The solution is heavily dependent on Entity Framework as the data access.
Is there a generic way for Entity Framework to read and write ALL these code tables without their entity models defined, like how you can read and write generic DataTables using ADO.NET?
Yes, there are couple of ways by which you can create tables at code side then either using code first approach or using publish project mechanism you can generate tables in SQL server using entity framework.
In the latter approach, you can create a separate project where you can write SQL for your various tables. This project should target SQL Server. You can right click on this project and click on publish option for updating all your tables inside SQL server.

Using Data Annotations for SQLite in Entity Framework Core

I am using the Entity Framework Core to interface my SQLite database. I want to set a minimum and maximum range for the field ExitSide in my model Station:
using System.ComponentModel.DataAnnotations;
...
class Station
{
public int StationId { get; set; }
[Range(0,2)]
public int ExitSide { get; set; }
}
But somehow it seems to get ignored. I am still able to create Stations with ExitSide=5 for example. What am I doing wrong?
EF Core does not currently recognise the Range data annotation

How to implement 3 tier approach using Entity Framework?

I know this question is asked many times, but I couldnt get a clear picture of what I need.
I have a WPF application which I need to redo using 3- Tier approach.
I have used Entity Framework for creating datamodel and using Linq queries for querying the data.
objCustomer = dbContext.Customers.Where(c => c.CustCode == oLoadDtl.CustNo).First();
I use Linq queries where ever I need in the program to get records from the database.
So, I just would like to know which all stuff comes under DAL, Business logic and UI layers.
Also, how do I separate them?
Can the entity datamodel considered as a DAL?
Is it a better idea to put the entity model in a separate class library?
It's better to create special class called DataAccess to encapsulate EntityFramework-invokes. For business logic you can create model classes, they will use DAL if needed. Other details depend on what your application should do.
For example:
//DAL
public class DataAccess
{
public static void GetCustomerByNumber(int number)
{
var objCustomer = dbContext.Customers.Where(c => c.CustCode == number).First();
return objCustomer;
}
}
//Models
public class Customer
{
public string Name { get; set; }
public int Number { get; set; }
public Customer GetCustomerByNumber(int number)
{
return DataAccess.GetCustomerByNumber(number);
}
public void ChangeProfile(ProfileInfo profile)
{
//...
}
}
Main things are extensibility, re-usability and efficiency of your solutions.

ADO.NET or OLE for multiple databases?

I have been tasked with a project at work of writing a class to connect to multiple different databases such as Oracle, SQL Server, Spatialite etc and get and set data values and I was wondering which of the two in the title you would recommend for this.
I have created a class that utilises OLE functionality in order to make connections and set and retrieve data as I thought ADO was more of an SQL Server specific technology. Is this the case or can ADO.NET be used for a variety of data sources? I have researched it quite a lot and most places that I have seen recommend OLE for multiple possible data sources whereas they recommend ADO for SQL Server.
Thanks
I can't see how OLE is going to provide a magic bullet for unifying the DAL. You want to use the data access framework that best suits the data source and abstract the implementation away from the application.
My guess is that you're hoping that using OLE will allow some unification of syntax. But this is not the case. Once you attempt to do something like paging, each data source is going to have its own quirks and how you connect to the source is not going to help unify the syntax differences. For example, in the case of paging, SQLite usings SKIP, TAKE. Oracle uses ROWNUM. Sql Server uses TOP.
I would approach the problem by creating a DAL that abstracts the entity classes away from the data source. Then you can use the connection type that is most suitable for the data source. For example, suppose my application wants to retrieve "Products" from a data source. My application would only know about the ProductFactory interface, not the specifics of the data source type. For example,
string id = "0000001";
IProductFactory factory = FactoryManager.GetProductFactory();
Product p = factory.Get(id);
In the example below, I implement the Oracle data access tier for the Product interfaces using ODP.Net (the best data access components for an Oracle data source). Then the data access tier looks like this:
IProductFactory:
public interface IProductFactory: IEntityFactory
{
Product Get(string productId);
IList<Product> GetAll();
int GetAllCount();
}
Product:
public class Product : IEntity<Product>
{
public string ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
#region IEntity<Product> Members
public Product MapData(System.Data.IDataReader reader)
{
return new Product
{
Name = reader["name"] as string,
Description = reader["description"] as string
};
}
#endregion
}
Oracle ProductFactory
public class ProductFactory : EntityFactory, IProductFactory
{
#region IProductFactory Members
public Product Get(string productId)
{
Product p = null;
using (OracleConnection conn = new OracleConnection(ConnectionString))
{
using (OracleCommand cmd = new OracleCommand())
{
cmd.CommandText = "select * from product where productId = :productId";
cmd.Parameters.Add("productId", productId);
using (IDataReader reader = cmd.ExecuteReader())
{
p = new Product();
p.MapData(reader);
}
}
}
return p;
}
public IList<Product> GetAll()
{
throw new NotImplementedException();
}
public int GetAllCount()
{
throw new NotImplementedException();
}
#endregion
}
ADO.NET can be used to connect to any database with an ODBC connection. We use ADO.NET for pretty much everything (PostgreSQL, Oracle, MySQL, SQL Server, etc), and it is the core database access method of most ORM products.
I'd recommend you to abstract away the DAL (data access layer) through an interface, and then create multiple DALs one for each type of database.
Your task can become a lot easier if you use a provider based ORM such as Entity Framework for your DALs private code.
For the public part all you have to do is implement the interface contract and you're fine.

Entity Framework - Multiple Project support

I am looking into migrate a large project to Entity Framework 4.0 but am not sure if it can handle my inheritance scenario.
I have several projects that inherit from an object in the “main” project. Here is a sample base class:
namespace People
{
public class Person
{
public int age { get; set; }
public String firstName { get; set; }
public String lastName { get; set; }
}
}
and one of the sub-classes:
namespace People.LawEnforcement
{
public class PoliceOfficer : People.Person
{
public string badgeNumber { get; set; }
public string precinct { get; set; }
}
}
And this is what the project layout looks like:
People - People.Education - People.LawEnforcement http://img51.imageshack.us/img51/7293/efdemo.png
Some customers of the application will use classes from the People.LawEnforcement and other users will use People.Education and some will use both. I only ship the assembles that the users will need. So the Assembles act somewhat like plug-ins in that they add features to the core app.
Is there anyway in Entity Framework to support this scenario?
Based on this SO question I'm think something like this might work:
ctx.MetadataWorkspace.LoadFromAssembly(typeof(PoliceOfficer).Assembly);
But even if that works then it seams as if my EDMX file will need to know about all the projects. I would rather have each project contain the metadata for the classes in that project but I'm not sure if that is possible.
If this isn't possible with entity framework is there another solution (NHibernate, Active Record, etc.) that would work?
Yes this is possible, using the LoadFromAssembly(..) method you've already found.
... but it will only work if you have an specialized model (i.e. EDMX) for each distinct type of client application.
This is because EF (and most other ORMs) require a class for each entity in the model, so if some clients don't know about some classes, you will need a model without the corresponding entities -- i.e. a customized EDMX for each scenario.
To make it easier to create a new model for each client application, if I was you I'd use Code-Only following the best practices laid out on my blog, to make it easy to grab only the fragments of the model you need actually need.
Hope this helps
Alex
Alex is correct (+1), but I'd strongly urge you to reconsider your model. In the real world, a police officer is not a subtype of a person. Rather, it's an attribute of that person's employment. I think programmers frequently tend to over-emphasize inheritance at the expense of composition in object oriented design, but it's especially problematic in O/R mapping. Remember that an object instance can only ever have one type. When that object is stored in the database, the instance can only have that type for as long as it exists, across multiple application sessions. What if a person had two jobs, as a police officer and a teacher? Perhaps that scenario is unlikely, but the general problem is more common than you might expect.
More relevant to your question, I think you can solve your actual problem at hand by making your mapped entity model more generic, and your application-specific data projections on the entities rather than entities themselves. Consider entities like:
public class JobType
{
public Guid Id { get; set; }
// ...
}
public class Job
{
public JobType JobType { get; set; }
public string EmployeeNumber { get; set; }
}
public class Person
{
public EntityCollection<Job> Jobs { get; set; }
}
Now your law enforcement app can do:
var po = from p in Context.People
let poJob = p.Jobs.Where(j => j.JobType == JobType.PoliceOfficerId).FirstOrDefault()
where poJob != null
select new PoliceOfficer
{
Id = p.Id,
BadgeNumber = poJob.EmployeeNumber
};
Where PoliceOfficer is just a POCO, not a mapped entity of any kind.
And with that you've achieved your goal of having a common data model, but having the "job type specific" elements in separate projects.

Categories