|
1 | | -### Library Powered By |
2 | | - |
3 | | -This library is powered by [Entity Framework Extensions](https://entityframework-extensions.net/?z=github&y=entityframework-plus) |
4 | | - |
5 | | -<a href="https://entityframework-extensions.net/?z=github&y=entityframework-plus"> |
6 | | -<kbd> |
7 | | -<img src="https://zzzprojects.github.io/images/logo/entityframework-extensions-pub.jpg" alt="Entity Framework Extensions" /> |
8 | | -</kbd> |
9 | | -</a> |
10 | | - |
11 | | ---- |
12 | | - |
13 | 1 | # Entity Framework Plus |
14 | 2 | Improve Entity Framework performance and overcome limitations with MUST-HAVE features |
15 | 3 |
|
16 | | -## Download |
17 | | - |
18 | | -Full Version | NuGet | NuGet Install |
19 | | ------------- | :-------------: | :-------------: |
20 | | -Z.EntityFramework.Plus.EFCore | <a href="https://www.nuget.org/packages/Z.EntityFramework.Plus.EFCore/" target="_blank"><img src="https://zzzprojects.github.io/images/nuget/efcore-full-version-v.svg" alt="download" /></a><a href="https://www.nuget.org/packages/Z.EntityFramework.Plus.EFCore/" target="_blank"><img src="https://zzzprojects.github.io/images/nuget/efcore-full-version-d.svg" alt="" /></a> | ```PM> Install-Package Z.EntityFramework.Plus.EFCore``` |
21 | | -Z.EntityFramework.Plus.EF6 | <a href="https://www.nuget.org/packages/Z.EntityFramework.Plus.EF6/" target="_blank"><img src="https://zzzprojects.github.io/images/nuget/ef6-full-version-v.svg" alt="download" /></a><a href="https://www.nuget.org/packages/Z.EntityFramework.Plus.EF6/" target="_blank"><img src="https://zzzprojects.github.io/images/nuget/ef6-full-version-d.svg" alt="" /></a> | ```PM> Install-Package Z.EntityFramework.Plus.EF6``` |
22 | | -Z.EntityFramework.Plus.EF5 | <a href="https://www.nuget.org/packages/Z.EntityFramework.Plus.EF5/" target="_blank"><img src="https://zzzprojects.github.io/images/nuget/ef5-full-version-v.svg" alt="download" /></a><a href="https://www.nuget.org/packages/Z.EntityFramework.Plus.EF5/" target="_blank"><img src="https://zzzprojects.github.io/images/nuget/ef5-full-version-d.svg" alt="" /></a> | ```PM> Install-Package Z.EntityFramework.Plus.EF5``` |
23 | | - |
24 | | -<a href="https://entityframework-plus.net/download">More download options (Full and Standalone Version)</a> |
25 | | - |
26 | | -## Features |
27 | | -- Batch Operations |
28 | | - - [Batch Delete](https://entityframework-plus.net/ef-core-batch-delete) |
29 | | - - [Batch Update](https://entityframework-plus.net/ef-core-batch-update) |
30 | | -- LINQ |
31 | | - - [LINQ Dynamic](https://entityframework-plus.net/ef-core-linq-dynamic) |
32 | | -- Query |
33 | | - - [Query Cache](https://entityframework-plus.net/ef-core-query-cache) |
34 | | - - [Query Deferred](https://entityframework-plus.net/ef-core-query-deferred) |
35 | | - - [Query DbSetFilter](https://entityframework-plus.net/query-db-set-filter) |
36 | | - - [Query Filter](https://entityframework-plus.net/ef-core-query-filter) |
37 | | - - [Query Future](https://entityframework-plus.net/ef-core-query-future) |
38 | | - - [Query IncludeFilter](https://entityframework-plus.net/ef-core-query-include-filter) |
39 | | - - [Query IncludeOptimized](https://entityframework-plus.net/ef-core-query-include-optimized) |
40 | | -- [Audit](https://entityframework-plus.net/ef-core-audit) |
41 | | - |
42 | | ---- |
43 | | - |
44 | | -**Bulk Operations only available with [Entity Framework Extensions](http://entityframework-extensions.net/)** |
45 | | -- BulkSaveChanges |
46 | | -- BulkInsert |
47 | | -- BulkUpdate |
48 | | -- BulkDelete |
49 | | -- BulkMerge |
50 | | - |
51 | | ---- |
52 | | - |
53 | | -## Batch Delete |
54 | | -Deletes multiples rows in a single database roundtrip and without loading entities in the context. |
55 | | - |
56 | | -```csharp |
57 | | -// using Z.EntityFramework.Plus; // Don't forget to include this. |
58 | | -
|
59 | | -// DELETE all users which has been inactive for 2 years |
60 | | -ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) |
61 | | - .Delete(); |
62 | | - |
63 | | -// DELETE using a BatchSize |
64 | | -ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) |
65 | | - .Delete(x => x.BatchSize = 1000); |
66 | | -``` |
67 | | - |
68 | | -**Support:** EF5, EF6, EF Core |
69 | | - |
70 | | -**[Learn more](https://entityframework-plus.net/ef-core-batch-delete)** |
71 | | - |
72 | | -## Batch Update |
73 | | -Updates multiples rows using an expression in a single database roundtrip and without loading entities in the context. |
74 | | - |
75 | | -```csharp |
76 | | -// using Z.EntityFramework.Plus; // Don't forget to include this. |
77 | | -
|
78 | | -// UPDATE all users which has been inactive for 2 years |
79 | | -ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)) |
80 | | - .Update(x => new User() { IsSoftDeleted = 1 }); |
81 | | -``` |
82 | | - |
83 | | -**Support:** EF5, EF6, EF Core |
| 4 | +Read more on our [Website](https://entityframework-plus.net/). |
84 | 5 |
|
85 | | -**[Learn more](https://entityframework-plus.net/ef-core-batch-update)** |
| 6 | +## Downloads |
86 | 7 |
|
87 | | -## Query Cache |
88 | | -**Query cache is the second level cache for Entity Framework.** |
| 8 | +### EF Core |
89 | 9 |
|
90 | | -The result of the query is returned from the cache. If the query is not cached yet, the query is materialized and cached before being returned. |
| 10 | +[](https://www.nuget.org/packages/Z.EntityFramework.Plus.EFCore) |
| 11 | +[](https://www.nuget.org/packages/Z.EntityFramework.Plus.EFCore) |
91 | 12 |
|
92 | | -You can specify cache policy and cache tag to control CacheItem expiration. |
93 | | - |
94 | | -**Support:** |
95 | | - |
96 | | -_Cache Policy_ |
97 | | - |
98 | | -```csharp |
99 | | -// The query is cached using default QueryCacheManager options |
100 | | -var countries = ctx.Countries.Where(x => x.IsActive).FromCache(); |
101 | | - |
102 | | -// (EF5 | EF6) The query is cached for 2 hours |
103 | | -var states = ctx.States.Where(x => x.IsActive).FromCache(DateTime.Now.AddHours(2)); |
104 | | - |
105 | | -// (EF7) The query is cached for 2 hours without any activity |
106 | | -var options = new MemoryCacheEntryOptions() { SlidingExpiration = TimeSpan.FromHours(2)}; |
107 | | -var states = ctx.States.Where(x => x.IsActive).FromCache(options); |
108 | 13 | ``` |
109 | | - |
110 | | -_Cache Tags_ |
111 | | - |
112 | | -```csharp |
113 | | -var states = db.States.Where(x => x.IsActive).FromCache("countries", "states"); |
114 | | -var stateCount = db.States.Where(x => x.IsActive).DeferredCount().FromCache("countries", "states"); |
115 | | - |
116 | | -// Expire all cache entry using the "countries" tag |
117 | | -QueryCacheManager.ExpireTag("countries"); |
| 14 | +PM> Install-Package Z.EntityFramework.Plus.EFCore |
118 | 15 | ``` |
119 | 16 |
|
120 | | -**Support:** EF5, EF6, EF Core |
121 | | - |
122 | | -**[Learn more](https://entityframework-plus.net/ef-core-query-cache)** |
123 | | - |
124 | | -## Query Deferred |
125 | | -**Defer the execution of a query which is normally executed to allow some features like Query Cache and Query Future.** |
126 | | - |
127 | | -```csharp |
128 | | -// Oops! The query is already executed, we cannot use Query Cache or Query Future features |
129 | | -var count = ctx.Customers.Count(); |
| 17 | +### EF6 |
130 | 18 |
|
131 | | -// Query Cache |
132 | | -ctx.Customers.DeferredCount().FromCache(); |
| 19 | +[](https://www.nuget.org/packages/Z.EntityFramework.Plus.EF6) |
| 20 | +[](https://www.nuget.org/packages/Z.EntityFramework.Plus.EF6) |
133 | 21 |
|
134 | | -// Query Future |
135 | | -ctx.Customers.DeferredCount().FutureValue(); |
136 | 22 | ``` |
137 | | -> All LINQ extensions are supported: Count, First, FirstOrDefault, Sum, etc. |
138 | | -
|
139 | | -**Support:** EF5, EF6, EF Core |
140 | | - |
141 | | -**[Learn more](https://entityframework-plus.net/ef-core-query-deferred)** |
142 | | - |
143 | | -## Query Filter |
144 | | -**Filter query with predicate at global, instance or query level.** |
145 | | - |
146 | | -**Support:** |
147 | | - |
148 | | -_Global Filter_ |
149 | | -```csharp |
150 | | -// CREATE global filter |
151 | | -QueryFilterManager.Filter<Customer>(x => x.Where(c => c.IsActive)); |
152 | | - |
153 | | -var ctx = new EntityContext(); |
154 | | - |
155 | | -// TIP: Add this line in EntitiesContext constructor instead |
156 | | -QueryFilterManager.InitilizeGlobalFilter(ctx); |
157 | | - |
158 | | -// SELECT * FROM Customer WHERE IsActive = true |
159 | | -var customer = ctx.Customers.ToList(); |
| 23 | +PM> Install-Package Z.EntityFramework.Plus.EF6 |
160 | 24 | ``` |
161 | 25 |
|
162 | | -_Instance Filter_ |
163 | | -```csharp |
164 | | -var ctx = new EntityContext(); |
165 | | - |
166 | | -// CREATE filter |
167 | | -ctx.Filter<Customer>(x => x.Where(c => c.IsActive)); |
168 | | - |
169 | | -// SELECT * FROM Customer WHERE IsActive = true |
170 | | -var customer = ctx.Customers.ToList(); |
171 | | -``` |
172 | | - |
173 | | -_Query Filter_ |
174 | | -```csharp |
175 | | -var ctx = new EntityContext(); |
176 | | - |
177 | | -// CREATE filter disabled |
178 | | -ctx.Filter<Customer>(CustomEnum.EnumValue, x => x.Where(c => c.IsActive), false); |
179 | | - |
180 | | -// SELECT * FROM Customer WHERE IsActive = true |
181 | | -var customer = ctx.Customers.Filter(CustomEnum.EnumValue).ToList(); |
182 | | -``` |
183 | | - |
184 | | -**Support:** EF5, EF6, EF Core |
185 | | - |
186 | | -**[Learn more](https://entityframework-plus.net/ef-core-query-filter)** |
187 | | - |
188 | | -## Query Future |
189 | | -**Query Future allow to reduce database roundtrip by batching multiple queries in the same sql command.** |
190 | | - |
191 | | -All future query are stored in a pending list. When the first future query require a database roundtrip, all query are resolved in the same sql command instead of making a database roundtrip for every sql command. |
192 | | - |
193 | | -**Support:** |
194 | | - |
195 | | -_Future_ |
196 | | - |
197 | | -```csharp |
198 | | -// GET the states & countries list |
199 | | -var futureCountries = db.Countries.Where(x => x.IsActive).Future(); |
200 | | -var futureStates = db.States.Where(x => x.IsActive).Future(); |
201 | | - |
202 | | -// TRIGGER all pending queries (futureCountries & futureStates) |
203 | | -var countries = futureCountries.ToList(); |
204 | | -``` |
205 | | - |
206 | | -_FutureValue_ |
207 | | - |
208 | | -```csharp |
209 | | -// GET the first active customer and the number of avtive customers |
210 | | -var futureFirstCustomer = db.Customers.Where(x => x.IsActive).DeferredFirstOrDefault().FutureValue(); |
211 | | -var futureCustomerCount = db.Customers.Where(x => x.IsActive).DeferredCount().FutureValue(); |
212 | | - |
213 | | -// TRIGGER all pending queries (futureFirstCustomer & futureCustomerCount) |
214 | | -Customer firstCustomer = futureFirstCustomer.Value; |
215 | | -``` |
216 | | - |
217 | | -**Support:** EF5, EF6, EF Core |
218 | | - |
219 | | -**[Learn more](https://entityframework-plus.net/ef-core-query-future)** |
220 | | - |
221 | | -## Query IncludeFilter |
222 | | -Entity Framework already support eager loading however the major drawback is you cannot control what will be included. There is no way to load only active item or load only the first 10 comments. |
223 | | - |
224 | | -**EF+ Query Include** make it easy: |
225 | | -```csharp |
226 | | -var ctx = new EntityContext(); |
227 | | - |
228 | | -// Load only active comments |
229 | | -var posts = ctx.Post.IncludeFilter(x => x.Comments.Where(x => x.IsActive)); |
230 | | -``` |
231 | | - |
232 | | -**Support:** EF6, EF Core |
233 | | - |
234 | | -**[Learn more](https://entityframework-plus.net/ef-core-query-include-filter)** |
235 | | - |
236 | | -## Query IncludeOptimized |
237 | | -Improve SQL generate by Include and filter child collections at the same times! |
238 | | - |
239 | | -```csharp |
240 | | -var ctx = new EntityContext(); |
241 | | - |
242 | | -// Load only active comments using an optimized include |
243 | | -var posts = ctx.Post.IncludeOptimized(x => x.Comments.Where(x => x.IsActive)); |
244 | | -``` |
245 | | - |
246 | | -**Support:** EF5, EF6, EF Core |
247 | | - |
248 | | -**[Learn more](https://entityframework-plus.net/ef-core-query-include-optimized)** |
249 | | - |
250 | | -## Audit |
251 | | -Allow to easily track changes, exclude/include entity or property and auto save audit entries in the database. |
252 | | - |
253 | | -**Support:** |
254 | | - - AutoSave Audit |
255 | | - - Exclude & Include Entity |
256 | | - - Exclude & Include Property |
257 | | - - Format Value |
258 | | - - Ignore Events |
259 | | - - Property Unchanged |
260 | | - - Soft Add & Soft Delete |
261 | | - |
262 | | -```csharp |
263 | | -// using Z.EntityFramework.Plus; // Don't forget to include this. |
264 | | -
|
265 | | -var ctx = new EntityContext(); |
266 | | -// ... ctx changes ... |
267 | | -
|
268 | | -var audit = new Audit(); |
269 | | -audit.CreatedBy = "ZZZ Projects"; // Optional |
270 | | -ctx.SaveChanges(audit); |
271 | | - |
272 | | -// Access to all auditing information |
273 | | -var entries = audit.Entries; |
274 | | -foreach(var entry in entries) |
275 | | -{ |
276 | | - foreach(var property in entry.Properties) |
277 | | - { |
278 | | - } |
279 | | -} |
280 | | -``` |
281 | | - |
282 | | -AutoSave audit in your database |
283 | | -```csharp |
284 | | -AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) => |
285 | | - (context as EntityContext).AuditEntries.AddRange(audit.Entries); |
286 | | -``` |
287 | | - |
288 | | -**Support:** EF5, EF6, EF Core |
289 | | - |
290 | | -**[Learn more](https://entityframework-plus.net/ef-core-audit)** |
291 | | - |
292 | | -## Useful links |
| 26 | +## Sponsors |
293 | 27 |
|
294 | | -- [Website](https://entityframework-plus.net/) |
295 | | -- [Documentation](https://entityframework-plus.net/batch-delete) |
296 | | -- [Online Examples](https://entityframework-plus.net/online-examples) |
297 | | -- You can also consult tons of Entity Framework Plus questions on |
298 | | -[Stack Overflow](https://stackoverflow.com/questions/tagged/entity-framework-plus) |
| 28 | +ZZZ Projects owns and maintains **Entity Framework Plus** as part of our [mission](https://zzzprojects.com/mission) to add value to the .NET community |
299 | 29 |
|
300 | | -## Contribute |
| 30 | +Through [Entity Framework Extensions](https://entityframework-extensions.net/?utm_source=zzzprojects&utm_medium=entityframeworkplus) and [Dapper Plus](https://dapper-plus.net/?utm_source=zzzprojects&utm_medium=entityframeworkplus), we actively sponsor and help key open-source libraries grow. |
301 | 31 |
|
302 | | -The best way to contribute is by **spreading the word** about the library: |
| 32 | +[](https://entityframework-extensions.net/bulk-insert?utm_source=zzzprojects&utm_medium=entityframeworkplus) |
303 | 33 |
|
304 | | - - Blog it |
305 | | - - Comment it |
306 | | - - Star it |
307 | | - - Share it |
308 | | - |
309 | | -A **HUGE THANKS** for your help. |
| 34 | +[](https://dapper-plus.net/bulk-insert?utm_source=zzzprojects&utm_medium=entityframeworkplus) |
310 | 35 |
|
311 | 36 | ## More Projects |
312 | 37 |
|
|
0 commit comments