1398-08-15 19:40 تبدیل دیتابیس DataBaseFirst به CodeFirst
booysusa

 
درود بر همگی به ویژه مهندس حاجی شریفی گرامی

من یک برنامه دارم که دیتابیس آن به روش DataBaseFirst طراحی شده است، ولی من میخوام به صورت CodeFirst انجامش بدم
1. تبدیل دیتابیس DataBaseFirst به CodeFirst رو نمیدونم
2. تبدیل رابطه ها از DataBaseFirst به CodeFirst رو نمیدونم
3. کلا چند روزه دارم تلاش میکنم با توجه به کتاب ها و کمک گرفتن از اینترنت یه جوری خودم بنویسمش ولی نمی تونم دیگه مجبور شدم رو بیارم به همیار همیشگی سیمرغ


این اسکریپت دیتابیس هست
لینک دانلود

ممنون میشم مهندس یه کمی آموزش بدید و اگر بشته تبدیلش و سپس آپلودش کنید که عالی میشه

شب بخیر
1398-08-17 14:39
حاجی شریفی
مؤسس سایت
 
سلام
اول که موجودیت ها را در قالب کلاس خیلی ساده ایجاد میکنید بالای کلید جدول خصیصه [Key] را استفاده میکنید.
اگر کلید AutoNumber یا همان Identity باشد هم از خصیصه [DatabaseGenerated] استفاده میکنید.
نام جدول را هم خود EF از نام کلاس متوجه میشود ولی اگر نام جدول خاصی مد نظر بود و یا جهت محکم کاری میتوانید از خصیصه [Table] هم بالای کلاس استفاده کنید.

مانند این دو جدول:
[Table( "Role" )]
public class Role
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RoleID { get ; set ; }
public string RoleName { get ; set ; }
}

[Table( "RolePermission" )]
public class RolePermission
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RolePermissionID { get ; set ; }
public int ? RoleID { get ; set ; }
public int ? PermissionID { get ; set ; }
}


و اما روابط ...
جدول RolePermission مستقیم کلید خارجی از جدول Role دارد.
یک سطر جدول RolePermission میتواند فقط یک Role داشته باشد، پس در کلاس RolePermission چنین مینویسیم:
public virtual  Role Role { get ; set ; }


درمقابل جدول Role خودش کلید خارجی از RolePermission ندارد ولی یک سطر جدول Role میتواند با چندین سطر جدول RolePermission رابطه داشته باشد پس در کلاس Role چنین مینویسیم:
public virtual  ICollection<RolePermission> RolePermissions { get ; set ; }


همین!
اگر نام PrimaryKey ها و ForeignKey ها یکسان باشد و بطوری باشد که EF متوجه شود، نیازی به Attribute گذاری اضافه هم ندارید.
( مانند نام کلید خارجی RolePermission.RoleID که با نام کلید اصلی Role.RoleID یکسان است و EF متوجه رابطه میشود. )

با این وجود اگرنیاز به Attribute گذاری هم باشد میتوانید در نهایت کدی شبیه این داشته باشید.

using  System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace test {

[Table( "Role" )]
public class Role
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RoleID { get ; set ; }
public string RoleName { get ; set ; }

//[InverseProperty(nameof(RolePermission.Role))]
public virtual ICollection<RolePermission> RolePermissions { get ; set ; }
}

[Table( "RolePermission" )]
public class RolePermission
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RolePermissionID { get ; set ; }
public int ? RoleID { get ; set ; }
public int ? PermissionID { get ; set ; }

//[ForeignKey(nameof(RoleID))]
public virtual Role Role { get ; set ; }
}


موفق باشید.
1398-08-17 21:01
booysusa

 
درود و سپاس مهندس حاجی شریفی گرامی
از وقتی که در انجمن کدی که نوشتید و توضیحاتی را که دادید دیدم دارم تمرین میکنم، ولی کمی گیج شدم

کدهای کلاس هارو براتون میزارم ببینید کجای کارم مشکل داره

کلاس UserRole
public class UserRole
{
[Key]
public int UserID { get; set; }
public Nullable<int> RoleID { get; set; }

public virtual Role Role { get; set; }
public virtual User User { get; set; }
}



کلاس User
public class User
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserID { get; set; }
[Required]
[MaxLength(50)]
public string UserName { get; set; }
[MaxLength(50)]
public string Password { get; set; }
[MaxLength(50)]
public string FirstName { get; set; }
[MaxLength(50)]
public string LastName { get; set; }
[MaxLength(50)]
public string Email { get; set; }
[MaxLength(50)]
public string Mobile { get; set; }
public Nullable<byte> SecurityQuestion { get; set; }
[MaxLength(50)]
public string AnswerQuestion { get; set; }
public Nullable<bool> IsActive { get; set; }

public virtual UserRole UserRole { get; set; }
}




کلاس Role
public class Role
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RoleID { get; set; }
[MaxLength(50)]
public string RoleName { get; set; }

public virtual ICollection<UserRole> UserRoles { get; set; }
public virtual ICollection<RolePermission> RolePermissions { get; set; }
}


کلاس RolePermission
public class RolePermission
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int RolePermissionID { get; set; }
public Nullable<int> RoleID { get; set; }
public Nullable<int> PermissionID { get; set; }

public virtual Role Role { get; set; }
public virtual Permission Permission { get; set; }
}


کلاس Permission
public class Permission
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PermissionID { get; set; }
[MaxLength(50)]
public string PermissioName { get; set; }
public Nullable<int> Parent { get; set; }

public virtual ICollection<RolePermission> RolePermissions { get; set; }
}


من میخوام رابطه هام شبیه به این دیاگرام بشه



از Update-Database -Force برای آپدیت دیتابیسم که استفاده میکنم این خطا رو میده - البته خطاهایی دیگه هم داده ولی الان این رو نشون میده
Unable to determine the principal end of an association between the types 'CafeNetManagement.Models.User' and 'CafeNetManagement.Models.Tanzimat.UserRole'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.



مهندس این رو یه توضیحی میدید؟ چطور باید تنظیمش کنیم؟ و اگر مثلا بیش از 100 جدول داشتیم و روابط بین آن ها مختلف بود چطور باید تنظیمش کنیم؟
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//modelBuilder.Entity<Govahiha>()
// .HasRequired(g => g.Contact)
// .WithMany(c => c.Govahihas)
// .HasForeignKey(f => f.ContactId)
// .WillCascadeOnDelete(true);

//modelBuilder.Entity<User>().HasOptional(x => x.Accesslevel)
//.WithRequired(x => x.User)
//.WillCascadeOnDelete(true);
}



البته اگر بشه در کنار آموزش، اون دیتابیس رو هم تبدیل کنید تا عملی تر متوجه بشم ممنون میشم (ببخشید واقعا)
1398-08-18 21:54
حاجی شریفی
مؤسس سایت
 
سلام
در نگاه اول و خیلی سریع مشخص است که روابط جدول UserRole شما به وضوح مشکل دارد.
این جدول باید کلید دوبل داشته باشد تا خودش یک رابطه یک به چند با User و یک رابطه یک به چند با Role داشته باشد، تا در نهایت موجب شود User و Role با هم رابطه چند به چند داشته باشند.
رابطه صحیح شما چیزی شبیه این میشود.


البته جدول RolePermission هم شبیه جدول UserRole است.
جدول RolePermission هم میتوانید تک کلید RolePermissionID را نداشته باشد وبجایش کلید دوبل داشته باشد.

این هم نمونه سورس کد:
EF6Test.zip 18KB

در این سورس از دستورات زیر استفاده شد:
PM> Install-Package EntityFramework -Version 6.3.0
PM> Enable-Migrations
PM> Add-Migration init
PM> Update-Database

جهت کوچک سازی بسته دانلودی، فایل های EF را حذف کردم، پس از دانلود اینترنت تان وصل باشد تا بسته Restore شود.
یک دیتابیس خالی بسازید و ConnectionString را در فایل App.config اصلاح کنید.
پروژه را کامپایل کنید و Update-Database را اجرا کنید.
موفق باشید.




1398-08-19 00:28
booysusa

 
درودمهندس (با گوشی دارم پیام میدم)
مهندس در فیلم اموزشی که تهیه کردم و قسمتی از برناممو با سبک اون پیش مییرم اونجوری که تصویرشو پیوست کردم روابط جدول User و به سمت UserRole رو تنظیم کرده بود
1398-08-19 20:46
booysusa

 
با درود مهندس شریفی گرامی
فایل برنامه از طریق tm برای شما ارسال شد