.Net轻量级ORM-NPoco的使用方法

文章引用自NPoco官方Wiki,地址:https://github.com/schotime/NPoco/wiki,因公司网络不稳定,有时无法访问,特将其摘抄。

Home

Adam Schroder edited this page on 1 Jul 2016 ·  49 revisions
 

Welcome to the NPoco wiki! NPoco is a fork of PetaPoco with a handful of extra features.

Getting Started: Your first query

  
  
  1. public class User
  2. {
  3. public int UserId { get;set; }
  4. public string Email { get;set; }
  5. }
  6.  
  7. using (IDatabase db = new Database("connStringName"))
  8. {
  9. List<User> users = db.Fetch<User>("select userId, email from users");
  10. }

Note: Database needs to be disposed to close the connection (think of it as your connection object).

This works by mapping the column names to the property names on the User object. This is a case-insensitive match.
There is no mapping setup needed for this (query only) scenario.

Available on NuGet: 
Also checkout the JabbR room if you have a question. Here are the release notes.

Mapping

Adam Schroder edited this page on 21 Apr 2016 ·  10 revisions

By default no mapping is required. It will be assumed that the table name will be the class name and the primary key will be 'Id' if its not specified with the attributes below.

Basic mapping is done via attributes. The most used ones are:

  1. [TableName] This takes a "name" parameter which indicates the table for which the Poco class will be mapped to.

  2. [PrimaryKey] This has a "columnName" parameter which takes the column name of the primary key for the table. Multiple primary keys can be specified by separating the columns with a comma. There is also an "autoIncrement" property which is used to indicate whether the primary key column is auto incremented e.g. identity column in Sql Server. By default this is true. For Oracle there is also a "sequenceName" property which will be used when inserting data with Oracle.

  3. [Column] This is used if the column name does not match the property name.

  4. [Ignore] This property will be ignored and cannot be mapped to.

  5. [ResultColumn] Properties marked with the Result column can be mapped into, however these properties will not be included in inserts or updates. Note: These columns will need to be explicitly specified in the SQL. It will not be included in the auto generated SQL.

  6. [ComputedColumn] Properties with the Computed column attribute work the same way as the Result column attributes however they will be auto selected in the SQL.

  7. [SerializedColumn] (v3+ only) Properties with the Serialized column attribute will serialize their data with the default serializer unless changed by implementing a IColumnSerializer. There is a NPoco.JsonNet library which allows you to use the JsonNetColumnSerializer. These are configured once by:

      
      
  1. DatabaseFactory.ColumnSerializer = new JsonNetColumnSerializer();

Example

      
      
  1. [TableName("Users")]
  2. [PrimaryKey("UserId")]
  3. public class User
  4. {
  5. public int UserId { get;set; }
  6. [Column("emailAddress")]
  7. public string Email { get;set; }
  8. [ResultColumn]
  9. public string ExtraInfo { get;set; }
  10. [Ignore]
  11. public int Temp { get;set; }
  12. }

If you don't like attribute based mapping, the take a look at fluent / convention based mapping

Query Single Object

schotime edited this page on 27 Apr 2012 ·  3 revisions

Selecting an object from the database can be done in a few different ways.

By Id

The easiest way to load an object from the database is by passing the primary key to the SingleById<T>() method.

          
          
  1. IDatabase db = new Database("connStringName");
  2. User u = db.SingleById<User>(3);

Via SQL

Below you can see that only the where is specified. If you don't explicitly supply the select clause it will be automatically generated for you and the where will then be appended.

          
          
  1. User u = db.Single<User>("where emailaddress = @0", "email@domain.com");
  2. or
  3. User u = db.Single<User>("select u.* from users u where emailaddress = @0", "email@domain.com");

Both these methods have a 'OrDefault' method if you are unsure that the object will exist. If it doesn't exist and you don't use the 'OrDefault' override it will throw an exception.

There are also First<T> and FirstOfDefault<T> which will not throw an exception if more than 1 record is returned.

Create Read Update Delete

Ryan Gates edited this page on 28 Jun 2016 ·  5 revisions

This wiki page refers to the User class found here.

Inserting a new record

              
              
  1. IDatabase db = new Database("connStringName");
  2. User u = new User()
  3. {
  4. Email = "name@domain.com",
  5. LastLoggedIn = DateTime.UtcNow
  6. };
  7.  
  8. db.Insert(u);

This will insert the User object into the users table generating a new identity value. This value will be populated back into the object after the insert statement. For example, the following would be true.

Reading the new record

              
              
  1. var user = db.SingleById(u.UserId);
  2. Assert.AreEqual(u.Email, user.Email);

Updating the record

Once I have the object, I can update its properties. After calling the Update method, those changes will be persisted to the database.

              
              
  1. var user = db.SingleById(1);
  2. user.Email = "new@domain.com";
  3. db.Update(user);

Deleting the record

If I decide I no longer need the record I can delete it in a very similar fashion to Insert and Update. That is by passing the object to the Delete method. Just the primary key value can also be passed to the Delete method, however the generic type parameter will need to be specified.

              
              
  1. var user = db.SingleById(1);
  2. db.Delete(user);

or

              
              
  1. db.Delete<User>(1);

Upsert the record

This will insert a record if it is new or update an existing record if it already exists. Its existence is determined by its primary key.

              
              
  1. IDatabase db = new Database("connStringName");
  2. User u = new User()
  3. {
  4. Email = "name@domain.com",
  5. LastLoggedIn = DateTime.UtcNow
  6. };
  7.  
  8. db.Save(u);

Query List

schotime edited this page on 27 Apr 2012 ·  1 revision

Here are some of the ways to fetch multiple rows from the database.

Eager

1: Fetch all

                   
                   
  1. List<User> users = db.Fetch<User>();

2: Fetch with criteria

                   
                   
  1. List<User> users = db.Fetch<User>("where isActive = 1");

3: Fetch with raw SQL

                   
                   
  1. List<User> users = db.Fetch<User>("select u.* from users where u.isActive = 1");

Lazy

Warning: The following method Query<T> uses the yield keyword. It will only run the query when the results are being iterated over. Please use the Fetch<T> method if you don't fully understand this concept.

                   
                   
  1. List<User> users = db.Query<User>("select u.* from users where u.isActive = 1");

Query Paging

schotime edited this page on 23 Mar 2013 ·  3 revisions

There are two main methods used for paging.

Page<T>

                        
                        
  1. IDatabase db = new Database("connStringName");
  2. Page<T> pagedUsers = db.Page<User>(2, 10, "select u.* from users u order by userid");

where Page<T> is defined by:

                        
                        
  1. public class Page<T>
  2. {
  3. public long CurrentPage { get; set; }
  4. public long TotalPages { get; set; }
  5. public long TotalItems { get; set; }
  6. public long ItemsPerPage { get; set; }
  7. public List<T> Items { get; set; }
  8. }

Note: You must provide an order by statement in your SQL statement so that the query knows in which order you want your data to be paged.

The first parameter to the Page<T> method is the page number. This number begins at 1 for the first page. The second parameter is the size of the page. In the example above, the second page with 10 users in it will be returned.

SkipTake<T>

The SkipTake<T> method is very similar to the Skip and Take methods in LINQ. It has the same number of parameters as the Page<T> method, but instead of the first parameter being the page number, it is the number of records to skip. The second parameter is the number of records to return after x number of records have been skipped. To return the same results as the Page<T>method, the query would be as follows:

                        
                        
  1. List<User> users = db.SkipTake<User>(10, 10, "select u.* from users u order by userid");

The difference between the two methods is that SkipTake<T> returns a List<T> whereas Page<T>returns a Page<T> object, which has extra properties convenient for rendering a pager.

There is also an overload of Fetch<T> which has the same parameter signature of the Page<T>method but returns a List<T>.

SQL Transaction Support

MixERP edited this page on 6 Feb 2016 ·  1 revision

This wiki page refers to NPoco transaction support.

Example 1

                            
                            
  1. using (IDatabase db = new Database("connStringName"))
  2. {
  3. db.BeginTransaction();
  4. //Your CRUD operation here
  5. db.CompleteTransaction();
  6. }

Example 2

                            
                            
  1. using (IDatabase db = new Database("connStringName"))
  2. {
  3. using (var transaction = db.GetTransaction())
  4. {
  5. //Your CRUD operation here
  6. transaction.Complete();
  7. }
  8. }

Map to an Existing Object

schotime edited this page on 10 Nov 2012 ·  2 revisions

Using the methods SingleIntoSingleOrDefaultIntoFirstInto and FirstOrDefaultInto it is possible to map columns from the database onto an existing object. Only the columns in the query will be set on the existing object.

                                 
                                 
  1. public class User
  2. {
  3. public int UserId { get;set; }
  4. public string Email { get;set; }
  5. }
  6.  
  7. var user = new User() { UserId = 1 };
  8. IDatabase db = new Database("connStringName");
  9. db.SingleOrDefaultInto(user, "select Email from users where userid = @0", 1);

One to Many Query Helpers

Cody Balos edited this page on 16 Jun 2016 ·  11 revisions

These helpers allow you to map a query that has a one-to-many relationship to nested list objects. Given the following classes:

                                      
                                      
  1. public class UserDto
  2. {
  3. public int UserId { get; set; }
  4. public string Name { get; set; }
  5. public List<CarDto> Cars { get; set; }
  6. }
  7.  
  8. public class CarDto
  9. {
  10. public string Make { get; set; }
  11. public string Color { get; set; }
  12. }

and the following query:

                                      
                                      
  1. IDatabase db = new Database("connStringName");
  2.  
  3. //v2
  4. var users = db.FetchOneToMany<UserDto, CarDto>(x => x.UserId,
  5. "select u.*, c.* from Users u inner join Cars c on u.UserId = c.UserId order by u.UserId");
  6.  
  7. //v3
  8. var users = db.FetchOneToMany<UserDto>(x => x.Cars,
  9. "select u.*, c.* from Users u inner join Cars c on u.UserId = c.UserId order by u.UserId");

This will give you a list of UserDto objects and for each of these the list of CarDto's will also be populated.

Note:
1. The first parameter to this method is a lambda expression which identifies the unique property of the first object.
2. The order of the columns is extremely important. It must align with the order of the generic parameters defined. In this example the query specifies u.* then c* which maps to <UserDto, CarDto>.
3. If you are mapping to objects that are also used for inserting data then you will need to make sure you ignore the List<> property using the [Ignore] attribute.
4. If you are using an outer join for your query and you are expecting that some of the many's will not be populated, make sure to use the second lambda in the FetchOneToMany call. This should return the property of the primary of the many object. In the above example this might be x => x.CarId.
5. FetchOneToMany cannot be used to fetch nested one-to-many relationships, or multiple one-to-many relationships. For example, if UserDto also had a list of BoatsDto, only the CarDto list or the BoatsDto list can be loaded and mapped with one query.

Mapping to Nested Objects

Michael Ganss edited this page on 11 Jul 2016 ·  4 revisions

These helpers allow you to map a query to an object that has nested objects. Given the following classes:

                                       
                                       
  1. public class User
  2. {
  3. public int UserId { get; set; }
  4. public string Name { get; set; }
  5. public Address Address { get; set; }
  6. }
  7.  
  8. public class Address
  9. {
  10. public string Street { get; set; }
  11. public string City { get; set; }
  12. }

and the following query:

                                       
                                       
  1. IDatabase db = new Database("connStringName");
  2. var users = db.Fetch<User, Address>("select u.UserId, u.Name, u.Street, u.City from Users");

This will give you a list of User objects with the nested class Address mapped.

Note:

  1. The order of the columns is extremely important. The columns in the query need to be specified in the same order as the generic parameters are specified. eg. The User columns are specified first, then the Address columns next.
  2. If you are mapping to objects that are also used for inserting data then you will need to make sure you ignore the Address property using the [ResultColumn] attribute. From v3, you will additionally need the [ComplexMapping] attribute.

Dictionary and Object Array Queries

schotime edited this page on 23 Apr 2013 ·  6 revisions

Sometimes, you don't know the columns that will be returned from a query. This is where being able to map to a Dictionary<string,object>, or object[] comes in handy.

                                           
                                           
  1. var users = db.Fetch<Dictionary<string, object>>("select * from users");

or

                                           
                                           
  1. var users = db.Fetch<object[]>("select * from users");

Note: From NPoco version > 1.0.3, all array types (value types eg. string[]int[]double[]DateTime[] etc) will be a valid generic parameter.

Change tracking for updates

schotime edited this page on 30 Apr 2013 ·  4 revisions

Using the Snapshotter

The snapshot is used to track the changes to the entity, so that only the properties that have changed will be updated. In the following example only the new Name will be sent to the database, as the Age value is the same as it was when the snapshot was started.

                                               
                                               
  1. IDatabase db = new Database("connString");
  2. var user = db.SingleById<User>(1); // Name = "Ted", Age = 21
  3.  
  4. var snapshot = db.StartSnapshot(user); // Any changes after this will be recorded.
  5.  
  6. user.Name = "Bobby";
  7. user.Age = 21;
  8.  
  9. db.Update(user, snapshot.UpdatedColumns()); // Only the Name column will be updated

Only the changes that have been made before UpdatedColumns() is called will be included in the change-set.

Composite Primary Keys

Bryan Rayner edited this page on 13 Jul 2016 ·  2 revisions

Composite keys can be specified by placing a comma between the two column names in the [PrimaryKey] attribute.

                                                        
                                                        
  1. [TableName("Users")]
  2. [PrimaryKey("UserId,UserName")]
  3. public class User
  4. {
  5. public int UserId { get; set; }
  6. public string UserName { get;set; }
  7. }

When setting a composite key, the AutoIncrement attribute will always default false.

If you want to get one of these objects from the database using the SingleById group of methods then you can use an anonymous type.

                                                        
                                                        
  1. IDatabase db = new Database("connStringName");
  2. var user = db.SingleById<User>(new {UserId = 1, UserName = "user"});

Multiple Result Sets

James Kelly edited this page on 4 Feb 2014 ·  6 revisions

This feature enables you to map multiple queries with only one call to the database. The FetchMultiple method returns a Tuple<List<T>, List<T1>>.

Support: This is only supported on databases which can return multiple result sets, eg. NextResult() on IDataReader is implemented. Sql Server and Postgresql via Npgsql support this.

                                                             
                                                             
  1. IDatabase db = new Database("connStringName");
  2. Tuple<List<User>, List<Address>> data = db.FetchMultiple<User, Address>("select * from users;select * from addresses;");
  3. var users = data.Item1;
  4. var addresses = data.Item2;

Fluent mappings including conventional

Ricardo Rodriguez edited this page on 11 Dec 2015 ·  7 revisions

Fluent Mappings

To a mapping for a class you can inherit from Map<T> where T is the class you are mapping for.

                                                                  
                                                                  
  1. public class UserMapping : Map<User>
  2. {
  3. public UserMapping()
  4. {
  5. PrimaryKey(x => x.UserId);
  6. TableName("Users");
  7. Columns(x =>
  8. {
  9. x.Column(y => y.Name).Ignore();
  10. x.Column(y => y.Age).WithName("a_ge");
  11. });
  12. }
  13. }

Mappings can also inherit from Mappings and specify all mappings in once class using the For<>method.

                                                                  
                                                                  
  1. public class OurMappings : Mappings
  2. {
  3. public OurMappings()
  4. {
  5. For<User>().Columns( ....
  6. }
  7. }

Database Factory Setup

You only want to create the mappings once and we do this using a Database Factory.

                                                                  
                                                                  
  1. public void Application_Start()
  2. {
  3. MyFactory.Setup();
  4. }
                                                                  
                                                                  
  1. public static class MyFactory
  2. {
  3. public static DatabaseFactory DbFactory { get; set; }
  4.  
  5. public static void Setup()
  6. {
  7. var fluentConfig = FluentMappingConfiguration.Configure(new OurMappings());
  8. //or individual mappings
  9. //var fluentConfig = FluentMappingConfiguration.Configure(new UserMapping(), ....);
  10.  
  11. DbFactory = DatabaseFactory.Config(x =>
  12. {
  13. x.UsingDatabase(() => new Database("connString"));
  14. x.WithFluentConfig(fluentConfig);
  15. x.WithMapper(new Mapper());
  16. });
  17. }
  18. }

Then you can use it like so in your code.

                                                                  
                                                                  
  1. var database = MyFactory.DbFactory.GetDatabase();

If you are using a container then you could have something like

                                                                  
                                                                  
  1. For<IDatabase>().Use(() => MyFactory.DbFactory.GetDatabase());

Simple linq queries

Adam Schroder edited this page on 21 Apr 2016 ·  5 revisions

Query<T>

NPoco introduces a simple way to fetch an object using LINQ query. Here is a simple example.

                                                                       
                                                                       
  1. IDatabase db = new Database("connString");
  2. db.Query<User>().Where(x => x.Name == "Bob")
  3. .OrderBy(x => x.UserId)
  4. .Limit(10, 10)
  5. .ToList();

The LINQ keywords that are available are:

  • ProjectTo
  • Count
  • Any
  • Where
  • OrderBy
  • OrderByDescending
  • ThenBy
  • ThenByDescending
  • Limit
  • Include
  • IncludeMany

Here is how you do an IN clause:

                                                                       
                                                                       
  1. var users = db.Query<User>().Where(x => new[] {1,2,3,4}.Contains(x.UserId)).ToList();
  2. // or using the 'In' extension method
  3. var users = db.Query<User>().Where(x => x.UserId.In(new[] {1,2,3,4})).ToList();

There are also a number of string methods that can be used in the where clause. Here are a few examples:

                                                                       
                                                                       
  1. var users = db.Query<User>().Where(x => x.Name.StartsWith("Bo")).ToList();
  2. var users = db.Query<User>().Where(x => x.Name.EndsWith("ob")).ToList();
  3. var users = db.Query<User>().Where(x => x.Name.Contains("o")).ToList();
  4. var users = db.Query<User>().Where(x => x.Name.ToLower() == "bob").ToList();
  5. var users = db.Query<User>().Where(x => x.Name.ToUpper() == "BOB").ToList();

Note. Not all operators have been implemented so if you find one that is not but should be, please create an issue.

Query Provider

Adam Schroder edited this page on 3 Feb 2015 ·  11 revisions

Query<T>

Find all the users with a UserId greater than 50, order it by Name and only return 20 records offset by 40 (eg. page 3)

                                                                           
                                                                           
  1. var users = db.Query<User>()
  2. .Where(x => x.UserId > 50)
  3. .OrderBy(x => x.Name)
  4. .Limit(20, 40)
  5. .ToList();

Note: The query will only be run when ToList(), ToEnumerable(), or any of the scalar methods that return 1 value are called (eg. SingleCount etc.)

UpdateMany<T>

Update all of type T using a Where if necessary

                                                                           
                                                                           
  1. var list = new[] {1, 2, 3, 4};
  2.  
  3. // Update only the Name field using the template User passed
  4. // into Execute where the UserId in (1,2,3,4)
  5. // If you turn ExecuteDefaults on it won't
  6. // set default properties (eg. null, or 0 for int)
  7. db.UpdateMany<User>()
  8. .Where( x => x.UserId.In(list))
  9. //.ExcludeDefaults()
  10. .OnlyFields(x => x.Name)
  11. .Execute(new User() {Name = "test"});

Note: The query will only be run when Execute is called.

DeleteMany<T>

Delete all of type T using a Where if necessary

                                                                           
                                                                           
  1. var list = new[] {1, 2, 3, 4};
  2.  
  3. db.DeleteMany<User>()
  4. .Where(x => list.Contains(x.UserId))
  5. .Execute();

Note: The query will only be run when Execute is called.

Version column support

petsuter edited this page on 11 Aug 2015 ·  3 revisions

[VersionColumn]

A numeric version field can be used to detect conflicting updates:

                                                                              
                                                                              
  1. [TableName("Users")]
  2. [PrimaryKey("UserId")]
  3. public class User
  4. {
  5. public int UserId { get;set; }
  6. [VersionColumn("VersionInt", VersionColumnType.Number)]
  7. public long VersionInt { get; set; }
  8. }

Updates will automatically check and increment the version and throw DBConcurrencyException if it is outdated. This can be disabled by setting Database.VersionException = VersionExceptionHandling.Ignore.

In SQL Server a rowversion timestamp datatype can be used for the version column with VersionColumnType.RowVersion:

                                                                              
                                                                              
  1. [TableName("Users")]
  2. [PrimaryKey("UserId")]
  3. public class User
  4. {
  5. public int UserId { get;set; }
  6. [VersionColumn("Version", VersionColumnType.RowVersion)]
  7. public byte[] Version { get; set; }
  8. }

Sql Templating

Adam Schroder edited this page on 5 Dec 2013 ·  3 revisions

You can use the SqlBuilder to build queries up with conditional wheres, columns, orderby's etc.

                                                                                   
                                                                                   
  1. var sqlBuilder = new SqlBuilder();
  2. var template = sqlBuilder.AddTemplate("select * from users where age > @0 and /**where**/", 10);

Here you can specify one of WhereSelectJoinLeftJoinOrderByOrderByColsGroupByand Having The corresponding sql tokens are specified below.

                                                                                   
                                                                                   
  1. /// Adds a filter. The Where keyword still needs to be specified. Uses /**where**/
  2. public SqlBuilder Where(string sql, params object[] parameters)
  3.  
  4. /// Replaces the Select columns. Uses /**select**/
  5. public SqlBuilder Select(params string[] columns)
  6.  
  7. /// Adds an Inner Join. Uses /**join**/
  8. public SqlBuilder Join(string sql, params object[] parameters)
  9.  
  10. /// Adds a Left Join. Uses /**leftjoin**/
  11. public SqlBuilder LeftJoin(string sql, params object[] parameters)
  12.  
  13. /// Adds an Order By clause. Uses /**orderby**/
  14. public SqlBuilder OrderBy(string sql, params object[] parameters)
  15.  
  16. /// Adds columns in the Order By clause. Uses /**orderbycols**/
  17. public SqlBuilder OrderByCols(params string[] columns)
  18.  
  19. /// Adds a Group By clause. Uses /**groupby**/
  20. public SqlBuilder GroupBy(string sql, params object[] parameters)
  21.  
  22. /// Adds a Having clause. Uses /**having**/
  23. public SqlBuilder Having(string sql, params object[] parameters)

The statements can be chained and the parameters start from 0 for each new statement.

                                                                                   
                                                                                   
  1. sqlBuilder
  2. .Where("height >= @0", 176)
  3. .Where("weight > @0 and weight < @1", 30, 60);
  4.  
  5. var db = new Database("conn");
  6. db.Fetch<User>(template);

The templates can be used anywhere the Sql class can be used.

Debugging and Profiling

Sean Lynch edited this page on 12 Jul 2013 ·  6 revisions

There are a few ways to debug/profile NPoco. They are listed below, and are commonly done by inheriting from Database and overriding a specific method. Note: Make sure you instantiate your new class (MyDb as below) when creating a Database from then on.

Manual

                                                                                       
                                                                                       
  1. public class MyDb : Database
  2. {
  3. public MyDb(string connectionStringName) : base(connectionStringName) { }
  4. public override void OnExecutingCommand(IDbCommand cmd)
  5. {
  6. File.WriteAllText("log.txt", FormatCommand(cmd));
  7. }
  8. }

MiniProfiler

http://miniprofiler.com/

                                                                                       
                                                                                       
  1. public class MyDb : Database
  2. {
  3. public MyDb(string connectionStringName) : base(connectionStringName) { }
  4. public override IDbConnection OnConnectionOpened(IDbConnection conn)
  5. {
  6. return new ProfiledDbConnection((DbConnection)conn, MiniProfiler.Current);
  7. }
  8. }

Glimpse

http://getglimpse.com/

Glimpse will usually hook itself up by installing the following packages.

                                                                                      
                                                                                      
  1. Install-Package Glimpse.ADO
  2. Install-Package Glimpse.Mvc4 (or your mvc version)

Show last SQL executed on the ASP.NET error page

Credit: Sam Saffron

                                                                                       
                                                                                       
  1. public class MyDb : Database
  2. {
  3. public MyDb(string connectionStringName) : base(connectionStringName) { }
  4.  
  5. public override void OnException(Exception e)
  6. {
  7. base.OnException(e);
  8. e.Data["LastSQL"] = this.LastSQL;
  9. }
  10. }
                                                                                       
                                                                                       
  1. void Application_Error(object sender, EventArgs e)
  2. {
  3. var lastError = Server.GetLastError();
  4.  
  5. string sql = null;
  6. try
  7. {
  8. sql = lastError.Data["LastSQL"] as string;
  9. }
  10. catch
  11. {
  12. // skip it
  13. }
  14. if (sql == null) return;
  15.  
  16. var ex = new HttpUnhandledException("An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.", lastError);
  17.  
  18. Server.ClearError();
  19.  
  20. var html = ex.GetHtmlErrorMessage();
  21. html = html.Insert(html.IndexOf("<b>Stack Trace:</b>"), @"
  22. <b>Last Sql:</b><br><br>
  23. <table width='100%' bgcolor='#ffffccc'>
  24. <tbody>
  25. <tr>
  26. <td><code><pre>" + sql + @"</pre></code></td>
  27. </tr>
  28. </tbody>
  29. </table><br>");
  30.  
  31. Response.Write(html);
  32. Response.StatusCode = 500;
  33. Response.End();
  34. }

                                                   
                                                   
    • 2
      点赞
    • 2
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    在构建.NET Core Web应用程序时,仓储层和业务层是核心组成部分。仓储层负责与数据库进行交互和数据存取,业务层则处理业务规则和逻辑。 首先,我们需要定义仓储接口(例如IUserRepository)来描述与用户相关的操作方法,如添加用户、删除用户、更新用户信息等。然后,我们创建一个实现该接口的具体仓储类(例如UserRepository),在该类中通过Entity Framework Core或其他ORM工具与数据库进行交互。 接下来,我们需要实现业务层。业务层通过调用仓储接口中定义的方法来操作数据,并处理业务逻辑。我们可以创建一个用户服务类(例如UserService),在该类中注入仓储类的实例,并通过调用仓储类中的方法实现具体的用户操作,如创建用户、验证用户信息等。业务层还可以定义更高层次的业务逻辑,如校验用户信息、处理用户请求等。 在创建业务层的同时,我们还可以使用依赖注入(DI)容器,如ASP.NET Core内置的DI容器,为仓储类和业务类注入依赖关系。这样可以更好地实现解耦和可测试性。 在实现过程中,我们还可以使用一些设计模式来提高代码的可读性和可维护性。例如,可以使用工厂模式来创建仓储类和业务类的实例,使用仓储模式来定义仓储接口和具体仓储类的关系,使用策略模式来处理不同的业务规则等。 总而言之,通过一步步构建.NET Core Web应用程序的仓储层和业务层,我们可以实现数据的存储和操作,以及业务逻辑的处理和管理。这样可以有效地组织代码,提高应用程序的可维护性和扩展性。

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值