ممنون؛ در برنامه ای که از linq to sql استفاده شده. بخواهیم همین روش ( Unit of work ) رو پیاده کنیم چه کاری باید انجام بشه؟ با تشکر
نظرات مطالب
با LINQ نه ولی اگر دستی SP بنویسید ممکنه این SP شما نا امن باشد. یک مثال در اینجا:
http://services.odata.org/OData/OData.svc/Category(1)/Products?$top=2&$orderby=name \_______________________________________/ \__________________/ \__________________/ | | | service root URL resource path query options
http://services.odata.org/OData/OData.svc/Products
http://services.odata.org/OData/OData.svc/Products(1)/Supplier
http://services.odata.org/OData/OData.svc/Products/MostExpensive
http://services.odata.org/OData/OData.svc/GetProductsByCategoryId(categoryId=2)
http://services.odata.org/OData/OData.svc/Products(1)/Name
//filter http://services.odata.org/OData/OData.svc/Products?$filter=Name eq 'Milk' //orderby http://services.odata.org/OData/OData.svc/Products?$orderby=Name //skip http://services.odata.org/OData/OData.svc/Products?$skip=5 //top http://services.odata.org/OData/OData.svc/Products?$top=10 //expand http://services.odata.org/OData/OData.svc/Products?$expand=Category
>ng g m CustomValidators -m app.module --routing
>ng g c CustomValidators/user-register
>ng g cl CustomValidators/user
export class User { constructor( public username: string = "", public email: string = "", public password: string = "", public confirmPassword: string = "" ) {} }
>ng g d CustomValidators/EmailValidator -m custom-validators.module
import { Directive } from "@angular/core"; import { AbstractControl, NG_VALIDATORS, Validator } from "@angular/forms"; @Directive({ selector: "[appEmailValidator][formControlName],[appEmailValidator][formControl],[appEmailValidator][ngModel]", providers: [ { provide: NG_VALIDATORS, useExisting: EmailValidatorDirective, multi: true } ] }) export class EmailValidatorDirective implements Validator { validate(element: AbstractControl): { [key: string]: any } { const emailRegex = /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/; const valid = emailRegex.test(element.value); return valid ? null : { appEmailValidator: true }; } }
<input #email="ngModel" required appEmailValidator type="text" class="form-control" name="email" [(ngModel)]="model.email">
selector: "[appEmailValidator][formControlName],[appEmailValidator][formControl],[appEmailValidator][ngModel]",
"apps": [ { // ... "prefix": "app",
selector: "[appEmailValidator]"
providers: [ { provide: NG_VALIDATORS, useExisting: EmailValidatorDirective, multi: true }
export class EmailValidatorDirective implements Validator {
validate(element: AbstractControl): { [key: string]: any }
validate(element: AbstractControl): { [key: string]: any } { const emailRegex = /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/; const valid = emailRegex.test(element.value); return valid ? null : { appEmailValidator: true }; }
<input #email="ngModel" required appEmailValidator type="text" class="form-control" name="email" [(ngModel)]="model.email">
{ required:true }
{ minlength : { requiredLength : 3, actualLength : 1 } }
{ appEmailValidator: true }
<div class="alert alert-danger" *ngIf="email.errors.appEmailValidator"> The entered email is not valid. </div>
public password: string = "", public confirmPassword: string = ""
>ng g d CustomValidators/EqualValidator -m custom-validators.module
import { Directive, Attribute } from "@angular/core"; import { Validator, AbstractControl, NG_VALIDATORS } from "@angular/forms"; @Directive({ selector: "[appValidateEqual][formControlName],[appValidateEqual][formControl],[appValidateEqual][ngModel]", providers: [ { provide: NG_VALIDATORS, useExisting: EqualValidatorDirective, multi: true } ] }) export class EqualValidatorDirective implements Validator { constructor(@Attribute("compare-to") public compareToControl: string) {} validate(element: AbstractControl): { [key: string]: any } { const selfValue = element.value; const otherControl = element.root.get(this.compareToControl); console.log("EqualValidatorDirective", { thisControlValue: selfValue, otherControlValue: otherControl ? otherControl.value : null }); if (otherControl && selfValue !== otherControl.value) { return { appValidateEqual: true // Or a string such as 'Password mismatch.' or an abject. }; } if ( otherControl && otherControl.errors && selfValue === otherControl.value ) { delete otherControl.errors["appValidateEqual"]; if (!Object.keys(otherControl.errors).length) { otherControl.setErrors(null); } } return null; } }
export class EqualValidatorDirective implements Validator { constructor(@Attribute("compare-to") public compareToControl: string) {}
<input #password="ngModel" required type="password" class="form-control" appValidateEqual compare-to="confirmPassword" name="password" [(ngModel)]="model.password">
export class EqualValidatorDirective implements Validator { constructor(@Attribute("compare-to") public compareToControl: string) {} validate(element: AbstractControl): { [key: string]: any } { const selfValue = element.value; const otherControl = element.root.get(this.compareToControl); console.log("EqualValidatorDirective", { thisControlValue: selfValue, otherControlValue: otherControl ? otherControl.value : null });
if (otherControl && selfValue !== otherControl.value) { return { appValidateEqual: true // Or a string such as 'Password mismatch.' or an abject. }; }
if (otherControl && otherControl.errors && selfValue === otherControl.value) { delete otherControl.errors["appValidateEqual"]; if (!Object.keys(otherControl.errors).length) { otherControl.setErrors(null); } } return null;
import { NgForm } from "@angular/forms"; import { User } from "./../user"; import { Component, OnInit } from "@angular/core"; @Component({ selector: "app-user-register", templateUrl: "./user-register.component.html", styleUrls: ["./user-register.component.css"] }) export class UserRegisterComponent implements OnInit { model = new User(); constructor() {} ngOnInit() {} submitForm(form: NgForm) { console.log(this.model); console.log(form.value); } }
<div class="container"> <h3>Registration Form</h3> <form #form="ngForm" (submit)="submitForm(form)" novalidate>
<div class="form-group" [class.has-error]="username.invalid && username.touched"> <label class="control-label">User Name</label> <input #username="ngModel" required maxlength="8" minlength="4" type="text" class="form-control" name="username" [(ngModel)]="model.username"> <div *ngIf="username.invalid && username.touched"> <div class="alert alert-info"> errors: {{ username.errors | json }} </div> <div class="alert alert-danger" *ngIf="username.errors.required"> username is required. </div> <div class="alert alert-danger" *ngIf="username.errors.minlength"> username should be minimum {{username.errors.minlength.requiredLength}} characters. </div> <div class="alert alert-danger" *ngIf="username.errors.maxlength"> username should be max {{username.errors.maxlength.requiredLength}} characters. </div> </div> </div>
<div class="form-group" [class.has-error]="email.invalid && email.touched"> <label class="control-label">Email</label> <input #email="ngModel" required appEmailValidator type="text" class="form-control" name="email" [(ngModel)]="model.email"> <div *ngIf="email.invalid && email.touched"> <div class="alert alert-info"> errors: {{ email.errors | json }} </div> <div class="alert alert-danger" *ngIf="email.errors.required"> email is required. </div> <div class="alert alert-danger" *ngIf="email.errors.appEmailValidator"> The entered email is not valid. </div> </div> </div>
<div class="form-group" [class.has-error]="password.invalid && password.touched"> <label class="control-label">Password</label> <input #password="ngModel" required type="password" class="form-control" appValidateEqual compare-to="confirmPassword" name="password" [(ngModel)]="model.password"> <div *ngIf="password.invalid && password.touched"> <div class="alert alert-info"> errors: {{ password.errors | json }} </div> <div class="alert alert-danger" *ngIf="password.errors.required"> password is required. </div> <div class="alert alert-danger" *ngIf="password.errors.appValidateEqual"> Password mismatch. Please complete the confirmPassword . </div> </div> </div> <div class="form-group" [class.has-error]="confirmPassword.invalid && confirmPassword.touched"> <label class="control-label">Retype password</label> <input #confirmPassword="ngModel" required type="password" class="form-control" appValidateEqual compare-to="password" name="confirmPassword" [(ngModel)]="model.confirmPassword"> <div *ngIf="confirmPassword.invalid && confirmPassword.touched"> <div class="alert alert-info"> errors: {{ confirmPassword.errors | json }} </div> <div class="alert alert-danger" *ngIf="confirmPassword.errors.required"> confirmPassword is required. </div> <div class="alert alert-danger" *ngIf="confirmPassword.errors.appValidateEqual"> Password mismatch. </div> </div> </div>
<button class="btn btn-primary" [disabled]="form.invalid" type="submit">Ok</button> </form> </div>
>npm install >ng build --watch
>dotnet restore >dotnet watch run
using var dbContext = new MyDbContext(); var objectToDelete = await dbContext.Objects.FirstAsync(o => o.Id == id); dbContext.Objects.Remove(objectToDelete); await dbContext.SaveChangesAsync();
using var dbContext = new MyDbContext(); var objectToDelete = new MyObject { Id = id }; dbContext.Objects.Remove(objectToDelete); await dbContext.SaveChangesAsync();
await dbContext.Objects.Where(x => x.Id == id).ExecuteDeleteAsync();
public class User { public int Id { get; set; } public required string FirstName { get; set; } public required string LastName { get; set; } public virtual List<Book> Books { get; set; } = new(); public virtual Address? Address { get; set; } } public class Book { public int Id { get; set; } public required string Type { get; set; } public required string Name { get; set; } public virtual User User { get; set; } = default!; public int UserId { get; set; } } public class Address { public int Id { get; set; } public required string Street { get; set; } public virtual User User { get; set; } = default!; public int UserId { get; set; } }
public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<User> Users { get; set; } = default!; public DbSet<Book> Books { get; set; } = default!; public DbSet<Address> Addresses { get; set; } = default!; }
context.Books.Where(book => book.Name.Contains("1")).ExecuteDelete();
DELETE FROM [b] FROM [Books] AS [b] WHERE [b].[Name] LIKE N'%1%'
context.Users.Where(user => user.Id <= 500).ExecuteDelete();
DELETE FROM [u] FROM [Users] AS [u] WHERE [u].[Id] <= 500 The DELETE statement conflicted with the REFERENCE constraint "FK_Books_Users_UserId". The conflict occurred in database "EF7BulkOperations", table "dbo.Books", column 'UserId'.
public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<User> Users { get; set; } = default!; public DbSet<Book> Books { get; set; } = default!; public DbSet<Address> Addresses { get; set; } = default!; protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder .Entity<User>() .HasMany(user => user.Books) .WithOne(book => book.User) .OnDelete(DeleteBehavior.Cascade); modelBuilder .Entity<User>() .HasOne(user => user.Address) .WithOne(address => address.User) .HasForeignKey<Address>(address => address.UserId) .OnDelete(DeleteBehavior.Cascade); } }
context.Users.Where(user => user.Id <= 400) .ExecuteUpdate(p => p.SetProperty(user => user.LastName, user => "Updated"));
UPDATE [u] SET [u].[LastName] = N'Updated' FROM [Users] AS [u] WHERE [u].[Id] <= 400
context.Users.Where(user => user.Id <= 300) .ExecuteUpdate(p => p.SetProperty(user => user.LastName, user => "Updated" + user.LastName));
UPDATE [u] SET [u].[LastName] = N'Updated' + [u].[LastName] FROM [Users] AS [u] WHERE [u].[Id] <= 300
context.Users.Where(user => user.Id <= 800) .ExecuteUpdate(p => p.SetProperty(user => user.LastName, user => "Updated" + user.LastName) .SetProperty(user => user.FirstName, user => "Updated" + user.FirstName));
UPDATE [u] SET [u].[FirstName] = N'Updated' + [u].[FirstName], [u].[LastName] = N'Updated' + [u].[LastName] FROM [Users] AS [u] WHERE [u].[Id] <= 800