Skip to content

Commit db877ea

Browse files
committed
Document the possibility of using EF6 interceptors.
1 parent 2041bfd commit db877ea

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

doc/index.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,61 @@ In PostgreSQL, this implicitly uses `template1` as the template - anything exist
3232
be copied to your new database. If you wish to change the database used as a template, you can specify
3333
the `EF Template Database` connection string parameter. For more info see the
3434
[PostgreSQL docs](https://www.postgresql.org/docs/current/static/sql-createdatabase.html).
35+
36+
## Customizing DataReader Behavior ##
37+
38+
You can use [an Entity Framework 6 IDbCommandInterceptor](https://msdn.microsoft.com/en-us/library/dn469464(v=vs.113).aspx) to wrap the `DataReader` instance returned by Npgsql when Entity Framework executes queries. This is possible using a ```DbConfiguration``` class.
39+
40+
Example use cases:
41+
- Forcing all returned ```DateTime``` and ```DateTimeOffset``` values to be in the UTC timezone.
42+
- Preventing accidental insertion of DateTime values having ```DateTimeKind.Unspecified```.
43+
- Forcing all postgres date/time types to be returned to Entity Framework as ```DateTimeOffset```.
44+
45+
```c#
46+
[DbConfigurationType(typeof(AppDbContextConfiguration))]
47+
public class AppDbContext : DbContext
48+
{
49+
// ...
50+
}
51+
52+
public class AppDbContextConfiguration : DbConfiguration
53+
{
54+
public AppDbContextConfiguration()
55+
{
56+
this.AddInterceptor(new MyEntityFrameworkInterceptor());
57+
}
58+
}
59+
60+
class MyEntityFrameworkInterceptor : DbCommandInterceptor
61+
{
62+
public override void ReaderExecuted(
63+
DbCommand command,
64+
DbCommandInterceptionContext<DbDataReader> interceptionContext)
65+
{
66+
if (interceptionContext.Result == null) return;
67+
interceptionContext.Result = new WrappingDbDataReader(interceptionContext.Result);
68+
}
69+
70+
public override void ScalarExecuted(
71+
DbCommand command,
72+
DbCommandInterceptionContext<object> interceptionContext)
73+
{
74+
interceptionContext.Result = ModifyReturnValues(interceptionContext.Result);
75+
}
76+
77+
static object ModifyReturnValues(object result)
78+
{
79+
// Transform and then
80+
return result;
81+
}
82+
}
83+
84+
class WrappingDbDataReader : DbDataReader, IDataReader
85+
{
86+
// Wrap an existing DbDataReader, proxy all calls to the underlying instance,
87+
// modify return values and/or parameters as needed...
88+
public WrappingDbDataReader(DbDataReader reader)
89+
{
90+
}
91+
}
92+
```

0 commit comments

Comments
 (0)