The context of this article
Operating system: Win7 x64 Ultimate
Development tools: Visual Studio 2013
First, preface
In most of the previously developed scenarios, the development language used is C #, the use of the database is SQL Server, such a combination of the Entity Framework such an ORM, since the use of the Entity Framework, can not be thrown off. This time for some historical reasons, the database must use Oracle, in fact, I do not like Oracle, such a database to my impression is used, whether it is to install the client, configure the connection, are too laborious.
Some things, you really have to bite the bullet to try, you do not do, will never understand. Since my previous project entity Framewor +sql Server is more commonly used, it is already familiar to ORM such as the Entity Framework, and the Entity Framework's database first and model first , when using, always encounter some problems, such as table field maintenance, only through the designer, update, if the table a lot of words, the designer display is very slow, update also often error, so I always use code first. This time, since it was Oracle, I thought it would be easy to change the reference or connect the string (if something really happens later).
second, ODP. NET installation
First search, know a odp.net, official description: Oracle data Provider for. Net (odp.net) features optimized ADO data access to the Oracle Datab Ase. Odp.net allows developers to take advantage of the advanced Oracle database functionality, including Real application Clusters , XML DB, and advanced security. The data provider can used with the latest. NET Framework 4.5.1 version. This odp.net, like Microsoft's System.Data.OracleClient, is a driver for Oracle database access, but Odp.net was developed by Oracle himself, and maybe some people would think that it would be OK to replace the reference in the project, but I thought so at first, and then I checked some Data only understand, System.Data.OracleClient use is Oracle's "minimum Driver", use should not need to install Oracle client, I have not practiced, used friends can help prove under. Then saw System.Data.OracleClient namespace's introduction: The System.Data.OracleClient namespace is the. NET Framework Data Provider for Oracle.this types in System.Data.OracleClient is deprecated and would be removed in a future version of the. NET Framework . For more information, see Oracle and ADO. NET. The most important thing I've seen is that System.Data.OracleClient is deprecated and will not be visible in the future. NET Framework. So it's best to use odp.net.
First to download odp.net, this to the Oracle server-side version of the corresponding, I use the Oracle 11g, so downloaded odac1120320xcopy_32bit, my operating system is x64, can download 32-bit and 64-bit, Initially downloaded 64-bit, but when running the Web site in IIS 7.5, it prompts "Could not load file or assembly ' oracle.dataaccess ' or one of its dependencies. An attempt is made to load a program with an incorrect format. "so I downloaded the 32 bit if the advanced setting in IIS 7.5 under Enable 32-bit Applications set to True, will be able to run normally, 64-bit under if Enable 32-bit applications set to false estimate also line, for the odp.net installation, which has detailed introduction, the correct installation is very important.
This part of Oracle is complete, the following is the ORM choice, decompression odp.net, in Odp.net4\odp.net\doc see a readme.htm, open carefully read, see this "odp.net 11.2.0.3 does not Support Code First nor the DbContext APIs. The moment was shaken. After the Oracle community see the Community admin answer Odp.net does not support EF Code first yet. For the next odp.net release (ODAC 12c Release 3), Oracle plans-to-support this feature. The plan is to release sometime in 2014. I just feel that this big Oracle's reaction is really slow. Therefore, can only give up the Entity Framework, listen to friends recommend that can use fluent NHibernate.
Third, Fluent nhibernate configuration
So decided to try, in VS2013 quoted Fluentnhibernate,install-package Fluentnhibernate-version 1.4.0, is currently the latest version. The next step is to build the foundation.
Because in the way of inheriting Classmap, a database table will write 2 entities, it feels too troublesome, I use automapping, the Entity and database table one by one correspond, do not consider the multi-table association problem.
The first is a dbcontext:
namespace Test.DataAccess.FNhibernate
{
public class DBContext
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
InitializeSessionFactory();
}
return _sessionFactory;
}
}
private static void InitializeSessionFactory()
{
string connectionString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.1.1.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)));User Id=test;Password=test123;";
var cfg = new DBConfiguration();
_sessionFactory = Fluently.Configure().Database(
OracleClientConfiguration.Oracle10
.ConnectionString(connectionString)
.Provider<NHibernate.Connection.DriverConnectionProvider>()
.Driver<NHibernate.Driver.OracleClientDriver>()
)
.Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<PRODUCT>(cfg).Conventions.Setup(c =>
{
c.Add<PrimaryKeyConvention>();
c.Add<CascadeConvention>();
})))
.BuildSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
/// <summary>
/// 这个暂时用,可能重复
/// </summary>
/// <returns></returns>
public static long GenerateID()
{
long i = 1;
foreach (byte b in Guid.NewGuid().ToByteArray())
{
i *= ((int)b + 1);
}
string number = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 1000000000);
return long.Parse(number);
}
}
}
View Code
Next is an entity that corresponds to the database table product:
namespace Test.DataAccess.FNhibernate.DB
{
public class PRODUCT
{
public virtual int PRODUCT_ID { get; set; }
public virtual string PRODUCT_NAME { get; set; }
}
}
View Code
Next is the mapping relationship:
namespace Test.DataAccess.FNhibernate
{ public class DBConfiguration : DefaultAutomappingConfiguration
{ public override bool ShouldMap(Type type)
{ return type.Namespace == "TEST.DataAccess.FNhibernate.DB";
} public override bool IsId(Member member)
{ string className = member.DeclaringType.Name; if (member.Name == className + "_ID")
{ return true;
} return false;
}
}
}
View Code
Specify how the primary key is to be generated: (Here is the manual assignment, which is to call the Generateid () method in DbContext when saving)
namespace HeLi.DataAccess.FNhibernate
{ public class PrimaryKeyConvention : IIdConvention
{ public void Apply(IIdentityInstance instance)
{ var type = instance.EntityType; if (type.Name == typeof(PRODUCT).Name)
{
instance.GeneratedBy.Assigned();
}
}
}
}
View Code
Iv. Testing
Using (var session = DBContext.OpenSession())
{
Using (var tran = session.BeginTransaction())
{
Var list = session.CreateCriteria(typeof(PRODUCT)).List<PRODUCT>();//Remove the entire table
Var dbUser = session.QueryOver<PRODUCT>().Where(p => p.PORUDCTID = 1).SingleOrDefault();
If (dbUser != null)
{
dbUser.PRODUCT_NAME = "mirror";
session.SaveOrUpdate(dbUser);
}
Var product = new PRODUCT();
product.PRODUCT_ID = DBContext.GenerateID();
product.PRODUCT_NAME = "box";
session.Save(product);
tran.Commit();
}
}
View Code
PS: Because it is an afterthought, there is no time to organize the demo, no full code download, Hope it can help you.
Reference reading:
Http://www.oracle.com/technetwork/topics/dotnet/index-085163.html
Http://dba.stackexchange.com/questions/44470/why-oracle-sql-developer-does-not-need-oracle-client
Http://msdn.microsoft.com/en-us/library/system.data.oracleclient (v=vs.110). aspx
http://www.thebestcsharpprogrammerintheworld.com/blogs/ Connect-to-an-oracle-database-without-an-oracle-client.aspx http://www.oracle.com/technetwork/database/windows/ Downloads/utilsoft-087491.html
One Oracle 11g+fluentnhibernate automapping combination attempt