نمایش نتایج 1 تا 4 از 4

نام تاپیک: ایجاد رابطه کلاس های خودمان با کلاس های Identity چگونه است

  1. #1

    Lightbulb ایجاد رابطه کلاس های خودمان با کلاس های Identity چگونه است

    سلام دوستان وقت بخیر.
    فرض کنید کلاسی به نام Customer داریم، Identity هم در پروژه فعال کردیم. AspNetUsers هم که اطلاعات کاربران سایت در خودش نگه داری میکند.

    آیا برای ایجاد رابطه بین کلاس Customer, AspNetUsers باید در Migration رابطه یک به یک آنها را تعریف کنیم؟ اصولا این کار منطقی است؟ چه زمان هایی باید رابطه ها در Migration تعریف کنیم؟ چرا مثلا در FluentApi این کار نمیکنیم؟

    ممنون میشم راهنمایی بفرمائید.

  2. #2
    بنیان گذار Barnamenevis آواتار مهدی کرامتی
    تاریخ عضویت
    اسفند 1381
    محل زندگی
    کرج، گلشهر
    سن
    46
    پست
    6,379

    نقل قول: ایجاد رابطه کلاس های خودمان با کلاس های Identity چگونه است

    تو این جور سناریو ها من معمولا یک کلاس User از IdentityUser ارث بری می کنم (مثلا اسمش رو میگذارم ApplicationUser) و موقع تعریف وفعال کردن Identity، این کلاس رو بعنوان نماینده جدول و موجودیت Users معرفی می کنم. در این حالت، دستت باز خواهد بود که در کلاس های دیگه از طریق تعریف پراپرتی ای از جنس ApplicationUser و البته، تعبیه کردن پراپرتی UserID، بصورتی که جنس اون پراپرتی با جنس کلید ApplicationUser یکسان باشه، مثلا اگر پراپرتی کلید در ApplicationUser از جنس Guid، یا String، یا int است، جنس این پراپرتی هم همون باشه، بین موجودیت User و کلاس/موجودیت مورد نظر ارتباط برقرار می کنم.
    برای انجام کاری که گفتم، در کلاس ApplcationDbContext، در رویداد override شده OnModelCreating این تغییرات رو دادم:
        public class ApplicationDbContext : IdentityDbContext<
    ApplicationUser,
    ApplicationRole,
    int,
    ApplicationUserClaim,
    ApplicationUserRole,
    ApplicationUserLogin,
    ApplicationRoleClaim,
    ApplicationUserToken> // Mehdi: Class declaration modified
    {
    public ApplicationDbContext(DbContextOptions<ApplicationD bContext> options)
    : base(options)
    {

    }
    public DbSet<Product> Product { get; set; }
    public DbSet<ProductCategory> ProductCategory { get; set; }
    public DbSet<Order> Orders { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<ApplicationUser>(b =>
    {
    // Each User can have many UserClaims
    b.HasMany(e => e.Claims)
    .WithOne(e => e.User)
    .HasForeignKey(uc => uc.UserId)
    .IsRequired();

    // Each User can have many UserLogins
    b.HasMany(e => e.Logins)
    .WithOne(e => e.User)
    .HasForeignKey(ul => ul.UserId)
    .IsRequired();

    // Each User can have many UserTokens
    b.HasMany(e => e.Tokens)
    .WithOne(e => e.User)
    .HasForeignKey(ut => ut.UserId)
    .IsRequired();

    // Each User can have many entries in the UserRole join table
    b.HasMany(e => e.UserRoles)
    .WithOne(e => e.User)
    .HasForeignKey(ur => ur.UserId)
    .IsRequired();
    });

    modelBuilder.Entity<ApplicationRole>(b =>
    {
    // Each Role can have many entries in the UserRole join table
    b.HasMany(e => e.UserRoles)
    .WithOne(e => e.Role)
    .HasForeignKey(ur => ur.RoleId)
    .IsRequired();

    // Each Role can have many associated RoleClaims
    b.HasMany(e => e.RoleClaims)
    .WithOne(e => e.Role)
    .HasForeignKey(rc => rc.RoleId)
    .IsRequired();
    });

    modelBuilder.Entity<ApplicationUser>(b =>
    {
    b.ToTable("Users");
    b.Property(e => e.Id).HasColumnName("UserID");
    b.Property(e => e.UserName).HasColumnName("Username");
    b.Property(e => e.NormalizedUserName).HasColumnName("NormalizedUse rname");
    });

    modelBuilder.Entity<ApplicationUserClaim>(b =>
    {
    b.ToTable("UserClaims");
    b.Property(e => e.Id).HasColumnName("UserClaimID");
    b.Property(e => e.UserId).HasColumnName("UserID");
    });

    modelBuilder.Entity<ApplicationUserLogin>(b =>
    {
    b.ToTable("UserLogins");
    b.Property(e => e.UserId).HasColumnName("UserID");
    });

    modelBuilder.Entity<ApplicationUserToken>(b =>
    {
    b.ToTable("UserTokens");
    b.Property(e => e.UserId).HasColumnName("UserID");
    });

    modelBuilder.Entity<ApplicationRole>(b =>
    {
    b.ToTable("Roles");
    b.Property(e => e.Id).HasColumnName("RoleID");
    b.Property(e => e.Name).HasColumnName("RoleName");
    b.Property(e => e.NormalizedName).HasColumnName("RoleNormalizedNam e");
    });

    modelBuilder.Entity<ApplicationRoleClaim>(b =>
    {
    b.ToTable("RoleClaims");
    b.Property(e => e.Id).HasColumnName("RoleClaimID");
    b.Property(e => e.RoleId).HasColumnName("RoleID");
    });

    modelBuilder.Entity<ApplicationUserRole>(b =>
    {
    b.ToTable("UserRoles");
    });
    }
    }


    کلاس های اصلاح شده مدل های مرتبط با Identity ام هم، اینهاست:
        public class ApplicationUser : IdentityUser<int>
    {
    // Additional Properties
    public virtual ICollection<ApplicationUserClaim> Claims { get; set; }
    public virtual ICollection<ApplicationUserLogin> Logins { get; set; }
    public virtual ICollection<ApplicationUserToken> Tokens { get; set; }
    public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
    public virtual ICollection<Order> Orders { get; set; }

    }

    public class ApplicationRole : IdentityRole<int>
    {
    public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }
    public virtual ICollection<ApplicationRoleClaim> RoleClaims { get; set; }
    }

    public class ApplicationUserRole : IdentityUserRole<int>
    {
    public virtual ApplicationUser User { get; set; }
    public virtual ApplicationRole Role { get; set; }
    }

    public class ApplicationUserClaim : IdentityUserClaim<int>
    {
    public virtual ApplicationUser User { get; set; }
    }

    public class ApplicationUserLogin : IdentityUserLogin<int>
    {
    public virtual ApplicationUser User { get; set; }
    }

    public class ApplicationRoleClaim : IdentityRoleClaim<int>
    {
    public virtual ApplicationRole Role { get; set; }
    }

    public class ApplicationUserToken : IdentityUserToken<int>
    {
    public virtual ApplicationUser User { get; set; }
    }

    همانطور که در تعریف کلاس ApplicationUser مشخص است، در اون کلاس یک رابطه به کلاس Orders تعریف کردم، بالطبع در کلاس Orders هم ستون های مربوطه به این کلاس رو اضافه کردم، به این شکل:
        public class Order
    {
    [Key]
    public int OrderID { get; set; }

    [Display(Name = "کاربر")]
    public int UserID { get; set; }

    [Display(Name = "تاریخ سفارش")]
    [Required(ErrorMessage = "لطفا {0} را وارد کنید")]
    public DateTime OrderDate { get; set; }

    [Display(Name = "نهایی شده")]
    public bool OrderIsFinalized { get; set; }

    // Navigation Properties
    [ForeignKey("UserID")]
    public virtual ApplicationUser User { get; set; }
    }

    در کد فوق، هم پراپرتی UserID از جنس int تعریف شده، هم پراپرتی User، از جنس ApplicationUser، بالایش هم با افزودن صفت ForeignKey مشخص کردم که رابطه با کلاس User از طریق کدوم پراپرتی برقرار میشه. این ترکیب از ساخته شدن ستون ناخواسته اضافی در جدولهای مربوطه، جهت حفظ ارتباط جلوگیری می کنه و میگه که مقدار رکورد Parent در جدول Users در کدام ستون در جدول فرزند (Orders) نگهداری شود.

    و در نهایت، در فایل Startup، به این صورت در متد ConfigureServices این طوری اعلام کردم که کلاس User و Role ام چی هاست:
    services.AddIdentity<ApplicationUser, ApplicationRole>()


    تغییر عمده ای که در ترکیبات فوق دیده میشه اینه که در همه جداول مربوط به Identity، جنس ستون کلید رو int گرفتم. همچنین، اسم جدول های فوق، و اسم ستون های اصلی کلید رو هم عوض کردم.

  3. #3

    نقل قول: ایجاد رابطه کلاس های خودمان با کلاس های Identity چگونه است

    نقل قول نوشته شده توسط مهدی کرامتی مشاهده تاپیک
    تو این جور سناریو ها من معمولا یک کلاس User از IdentityUser ارث بری می کنم (مثلا اسمش رو میگذارم ApplicationUser) و موقع تعریف وفعال کردن Identity،
    با عرض سلام، آقای کرامتی عزیز، از راهنمایی دقیق شما خیلی ممنون هستم. من توی پروژه ای دیدم که مثلا برقراری رابطه applicationUser با Order در migration تعریف کرده بود! و از fluent استفاده نکرده بود. به نظرم استفاده از migration برای ایجاد رابطه بین کلاس ها، منطق کار و نگهداری کد خیلی سخت میکنه.
    آخرین ویرایش به وسیله sayanpro : سه شنبه 21 مرداد 1399 در 15:07 عصر

  4. #4
    بنیان گذار Barnamenevis آواتار مهدی کرامتی
    تاریخ عضویت
    اسفند 1381
    محل زندگی
    کرج، گلشهر
    سن
    46
    پست
    6,379

    نقل قول: ایجاد رابطه کلاس های خودمان با کلاس های Identity چگونه است

    نه تنها کار سختی است، بلکه روش اصولی ای نیست.

تاپیک های مشابه

  1. به دست اوردن اخرین مقدار identity
    نوشته شده توسط jokerhp در بخش T-SQL
    پاسخ: 2
    آخرین پست: چهارشنبه 28 بهمن 1394, 09:44 صبح
  2. پاسخ: 1
    آخرین پست: سه شنبه 06 مرداد 1394, 20:49 عصر
  3. معادل این دستورSQL Server در اکسس پیه SELECT @@IDentity AS 'Identity'
    نوشته شده توسط sg.programmer در بخش Access
    پاسخ: 1
    آخرین پست: دوشنبه 22 خرداد 1391, 10:17 صبح
  4. سوال: بدست آوردن آخرین سطر جدولی که Identity نداره
    نوشته شده توسط Open-Source در بخش SQL Server
    پاسخ: 5
    آخرین پست: پنج شنبه 12 فروردین 1389, 00:21 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •