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

نام تاپیک: نوشتن کوئری با مقادیر رابطه های چند به چند

  1. #1

    Lightbulb نوشتن کوئری با مقادیر رابطه های چند به چند

    با سلام


    من یک موجودیت فروشگاه دارم به شکل زیر :



    public class Shop : BaseContactInfo
    {
    public string Sevices { get; set; }
    public short CityId { get; set; }
    public City City { get; set; }
    public List<ShopCategory> ShopCategories { get; set; }
    }


    با توجه به کلاس فروشگاه من می تونه داخل چندین Category قراربگیره و همینطور برعکس ( رابطه چند به چند ) و من در Fluent api به این شکل رابطه دیتابیس رو ایجاد کردم :


    HasMany(x => x.ShopCategories).WithMany()
    .Map(x => x.ToTable("Tbl_ShopsCategories")
    .MapLeftKey("ShopId")
    .MapRightKey("CategoryId"));




    دیتابس و روابط کاملا درست هست . الان مشکل من این هستش که کوئری می خوام بزنم تمامی فروشگاه ها رو بیاره اما نمی دونم باید چیکار کنم از Include هم استفاده کردم اما هیچ مقداری رو نمی آره .

    خواستم در این رابطه راهنمایی کنید چطور لیستی برگردونم که هر موجودیت فروشگاه شامل لیست Category ها هم باشه .


    با تشکر

  2. #2
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    میتونید از SelcectMany استفاده کنید

    var list = dbo.Shops
    .SelectMany(e => e.ShopCategories,
    (sh, cat) => new YourViewModel
    {
    a = sh.field1,
    b = cat.field2,
    c = cat.field3
    });



    بدینصورت هم میشود عمل کرد

    public class vm
    {
    1-فیلد از مدل فروشگاه
    2-فیلد از مدل فروشگاه
    3 لیست جنریک از نوع category
    }



    کوئری هم بدنیصورت بنویسید

    var list = Shops.SelectMany(e => e.ShopCategories).Select(x=> new YourViewModel
    {
    فیلد مدل فروشگاه=x.,
    categorys= x.categorys//لیست جنریک


    });



    فقط یک سوال نحوه نمایش شما در ویو به چ صورت هست؟ نمایش منوی کشویی هست یا به صورت دیگر؟
    آخرین ویرایش به وسیله ali_md110 : شنبه 30 تیر 1397 در 20:47 عصر

  3. #3

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام

    مرسی بابت توضیحات خوبتون

    من می خوام این لیست رو داخل یک اکشن در Web API به صورت JSON برگردونم .

    کوئری اول درست کار می کرد ولی اینکه نام فروشگاه با هر کدام از Category ها رو به صورت یک Object جدا برمی گردوند .

    مد نظر من کوئری دوم شما هست که متاسفانه من vm رو ساختم کوئری رو نوشتم اونجایی که باید فیلد های vm رو مقدار دهی کنیم داخل select وقتی x رو می زدم فقط به فیلد های Category دسترسی داشتم و فیلد های خود Shop نبودند .

    مد نظر من یک خروجی به شکل زیر هست :



    ShopName : فروشگاه تهرانی
    Categories : فروش پوشاک , فروش مبلمان,فروش لوازم خانگی



    در حقیقت فیلد Categories من می خوام شامل رشته ای باشه که گروه های فروشگاهی من با , از هم جدا شده باشند

    View Model هم که ایجاد کردم به شکل زیر :

    public class ShopViewModel
    {
    public string ShopName { get; set; }
    public List<ShopCategory> Categories { get; set; }
    }



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

    تشکر از شما

  4. #4
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    شما میتونیداز Automapper کمک بگیرید
    ابتدا ویومدلتون را اصلاح کنید چون شما می خواهید رشته ها را با کاما بهم بچسبانید باید فیلد از نوع رشته تعریف کنید

    public class ShopViewModel
    {
    public string ShopName { get; set; }

    public string Categories { get; set; }

    }





    چون ef از توابع سی شارپ در بدنه خود پشتیبانی نمی کند باید از automapper بهره بریم
    لیست زیر به راحتی اون چیزی را که میخواین بهتون میده

    var li= _mapper.Map<List<ShopViewModel>>(Shops.Include(x=> x.ShopCategories));


    کلاس کانفیگ autommaper هم یادتون نره

    configuration.CreateMap<shop, ShopViewModel>()
    .ForMember(dest => dest.ShopName , opt => opt.MapFrom(src => src.ShopName ))

    .ForMember(dest => dest.Categories , mo => mo.MapFrom(src =>
    src.ShopCategories!= null
    ? string.Join(",", src.ShopCategories.Select(x => x.CatName).ToList())
    : ""));


    اگر از Automapper نمی خواید استفاده کنید باید ابتدا لیست زیر واکشی کنید

    var list=Shops.Include(x=> x.ShopCategories).tolist();
    var return=list.select(x=> new ShopViewModel{ShopName =x.shopname,
    Categories =
    string.Join(",", src.ShopCategories.Select(x => x.CatName)

    و سپش projection بزنید که این روش سربار داره و کند تر هست به دلیل اینکه یکبار داده از دیتابیس خوانده شده و سپس حلقه یا select مجدد روی آن اجرا میشود
    آخرین ویرایش به وسیله ali_md110 : یک شنبه 31 تیر 1397 در 15:26 عصر دلیل: بهم ریختگی کد

  5. #5

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام

    ممنون از راهنمایی های شما و عذر خواهی بابت سوالات متداول .

    من Autommaper رو نصب کردم و یک کلاس Configuration براش درست کردم که داخل فایل Globax هم Register می کنم ( طبق روندی که از قبل داشتم )


    public static class AutoMapperServiceManager
    {
    public static void Configure()
    {

    }

    }



    اما مشکل اینجاست که کد شما رو که می زارم CreateMap رو نمی شناسه و خطا می ده

    و اینکه کدی که برای برگردوندن لیست فرموده بودید من گذاشتم ولی زمانی که shops.Include رو می نویسم و x. رو می زنم هیچ مقداری نمی آره یعنی ShopCategories رو نمی شناسه . من کد زیر رو نوشتم :



    var shops = db.Shops;
    var li = Mapper.Map<List<ShopViewModel>>(shops.Include(x => x.ShopCategories));




    من تصویر هر دو موضوع رو هم ضمیمه کردم

    ممنون می شم بررسی کنید

    ممنون بابت وقتی که می زارید .
    عکس های ضمیمه عکس های ضمیمه
    • نوع فایل: jpg 1.jpg‏ (18.5 کیلوبایت, 61 دیدار)
    • نوع فایل: jpg 2.jpg‏ (57.1 کیلوبایت, 58 دیدار)

  6. #6
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    این خطای عدم شناسایی ShopCategories ربطی به Automapper نداره
    این در واقع یک لیست هست که بصورت پارامتر به automapper ارسال میشه
    شما میتونید این قسمت داخل پرانتر رو بیاریدش بیرون و بریزید توی متغیر دیگه و سپس ارسال کنید به mapper

    var shops = db.Shops.Include(x => x.ShopCategories
    var li = Mapper.Map<List<ShopViewModel>>(shops));

    چک کنید ببینید در این حالت ShopCategories شناسایی میشه؟اگر نشد که به نظر من همینطوره
    مشکل کار جای دیگست

  7. #7

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام و احترام


    چک کردم اما در این حالت هم ShopCategories رو نمی آره . به نظر شما مدل من ایرادی نداره ؟ یا اینکه نیاز نیست مثل روابط یک به چند سمت ShopCategory یک ICollection از Shop بزارم ؟

    برای فایل Config قسمت AutoMapper چیکار کنم که CreateMap رو نمی شناسه ؟ امکان داره Pakage درستی رو نصب نکرده باشم ؟ من پکیجی که اسمش دقیقا AutoMapper بود با لوگو قرمز رنگ نصب کردم

    تشکر از لطف شما من خیلی با روابط چند به چند کار نکردم و توی پروژه واقعی تقریبا اولین بار هست به همین دلیل سیستم فکریم ریخته بهم

    ممنون از شما

  8. #8
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    در روابط چند به چند دوسر رابطه حتما باید کالکشن متناظر داشته باشند و در ضورت نیاز با fluent یک تنظیماتی مثل خودتون میشه انجام داد


    this.HasMany(x => x.Shops)
    .WithMany(x => x.Categories)
    .Map(map =>
    {
    map.MapLeftKey("ShopId");
    map.MapRightKey("CatgoryId");
    map.ToTable("ShopCategories ");
    });



    تنظیمات Automapper شما صحیح نیست این مثالی که من پست قبلی زدم جهت بادآوری شما بود

    برای کار با automapper چند روش هست
    ساده ترینش کلاسهای پروفایل هست

    ابتدا یک کلاس پروفایل میسازیم

    public class ShopProfile : Profile
    {
    protected override void Configure()
    {
    this.CreateMap<source, dest>();
    // .ForMember(user => ......);

    کدهایی که قبلا فرستادم اینجا قرار بدید
    }

    public override string ProfileName
    {
    get { return this.GetType().Name; }
    }
    }




    باید automapper را رجیستر کرد
    در فایل استارت اپ قرار بدید

    Mapper.Initialize(cfg => ()
    {
    cfg.AddProfile<ShopProfile>();
    });
    Mapper.AssertConfigurationIsValid();


  9. #9

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام و احترام


    مرسی بابت پاسخ های زیادی که دادید . من از راه دومی که فرمودید تونستم خروجی بگیریم ولی به گفته خودتون و تستی که کردم کند هستش . من کل چیزی رو که پیاده سازی کردم برای استفاده از AutoMapper اینجا می زارم ممنون می شم بررسی کنید :


    ۱ - کلاس Shop من :



    public Shop()
    {
    this.ShopCategories = new List<ShopCategory>();
    this.Stones = new List<Stone>();
    }

    public string Sevices { get; set; }
    public short CityId { get; set; }
    public City City { get; set; }
    public virtual ICollection<ShopCategory> ShopCategories { get; set; }
    public virtual ICollection<Stone> Stones { get; set; }



    2 - کلاس ShopCategory


    public class ShopCategory : BaseEntity<byte>
    {

    public ShopCategory()
    {
    this.Shops = new List<Shop>();
    }

    public string Name { get; set; }
    public virtual ICollection<Shop> Shops { get; set; }
    }




    3 - کلاس Stone


    public Stone()
    {
    this.Shops= new List<Shop>();
    }

    public string Name { get; set; }
    public string Details { get; set; }
    public string Colors { get; set; }
    public string Resource { get; set; }
    public string Usage { get; set; }
    public string PriceStatus { get; set; }
    public virtual ICollection<StoneGallery> StoneGalleries { get; set; }
    public virtual ICollection<Shop> Shops { get; set; }




    * این موجودیت Stone جدید اضافه کردم دقیقا این مورد هم رابطه چند به چند داره با فروشگاه های که لیست سنگ های قابل ارائه رو مشخص می کنه


    4 - تنظیمات Fluent من


    ToTable("tbl_Shops");

    Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGenerated Option.Identity);
    Property(x => x.Sevices).HasMaxLength(2000).IsUnicode();

    HasRequired(x => x.City).WithMany(x=>x.Shops)
    .HasForeignKey(x => x.CityId)
    .WillCascadeOnDelete(false);


    HasMany(x => x.Stones).WithMany(x=>x.Shops)
    .Map(x => x.ToTable("tbl_ShopsStones")
    .MapLeftKey("ShopId")
    .MapRightKey("StoneId"));

    HasMany(x => x.ShopCategories).WithMany(x=>x.Shops)
    .Map(x => x.ToTable("Tbl_ShopsCategories")
    .MapLeftKey("ShopId")
    .MapRightKey("CategoryId"));





    5 - تنظیمات Autommaper که فرمودید :


    public class ShopProfile : Profile
    {
    protected void Configure()
    {
    this.CreateMap<Shop, ShopDemoViewModel>()
    .ForMember(dest => dest.ShopName, opt => opt.MapFrom(src => src.Title))

    .ForMember(dest => dest.Categories, mo => mo.MapFrom(src =>
    src.ShopCategories != null
    ? string.Join(",", src.ShopCategories.Select(x => x.Name).ToList())
    : ""));
    }

    public override string ProfileName
    {
    get { return this.GetType().Name; }
    }
    }



    6 - ریجیستر کردن تنظیمات در Globax و متد Application_Start


    protected void Application_Start()
    {
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Registe r);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.F ilters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    GlobalConfiguration.Configuration.Formatters.JsonF ormatter.MediaTypeMappings
    .Add(new System.Net.Http.Formatting.RequestHeaderMapping("A ccept",
    "text/html",
    StringComparison.InvariantCultureIgnoreCase,
    true,
    "application/json"));

    Mapper.Initialize(cfg =>
    {
    cfg.AddProfile<ShopProfile>();
    });
    Mapper.AssertConfigurationIsValid();


    }



    7 - فایل ShopDemoViewModel


    public class ShopDemoViewModel
    {
    public string ShopName { get; set; }

    public string Categories { get; set; }
    }




    8 - کد نوشته شده در کنترلر webapi


    public List<ShopDemoViewModel> Get()
    {
    var db = new ApplicationDbContext();

    var shops = db.Shops.Include("ShopCategories").Include("Stones ").ToList();
    var li = Mapper.Map<List<ShopDemoViewModel>>(shops).ToList( );

    return li;
    }





    => اولین مشکل این هست که Navigation برای من کار نمی کنه و حتما Include ها رو باید String اون رابطه رو بدم تا خروجی بده این خیلی مهم هست اگر می شه لطفا این رو بررسی بکنید من کجای کار اشتباه کردم کل دو سر رابطه ها و تنظیمات رو تصحیح کردم

    => دومین مشکل هم که خطای ضمیمه شده هستش که هیچ خروجی نمی ده



    تشکر بابت وقتی که می زارید .


    [COLOR=inherit !important]



    [/COLOR]
    عکس های ضمیمه عکس های ضمیمه

  10. #10
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    خطای automapper بابت این هست که شما در سمت مدل فیلدها و یا فیلدهای ناوبری دارید که در قسمت ویومدل ندارید و مپ نشده
    در ورژن های قدیم تر automapper این مپ نشدن نادیده گرفته میشد و خطایی نمی داد ولی اگر اشتباه نکنم شما باید جدیدترین ورژن داشته باشید
    در ورژن 6 باید یک تنظیم اضافه کنید تا این خطا بر طرف شود



    Mapper.Initialize(cfg => {
    cfg.IgnoreUnmapped();

    });



    و اگر شما ناوبری را بصورت لامبدا در دسترس ندارید شاید مشکل ef باشد یکبار از طریق nuget به روز رسانی کنید
    تمام فولدر های bin و obj را از پروژه هاتون حذف کنید و دوباره بیلد کنید



    در ضمن در کلاسهای مدل نیازی به سازنده ندارید و این وهله سازی کالکشن ها را هم حذف کنید
    یک مورد دیگر Tolist هم از این حذف کنید نیازی نیست

    db.Shops.Include("ShopCategories").Include("Stones ").ToList();
    آخرین ویرایش به وسیله ali_md110 : پنج شنبه 04 مرداد 1397 در 17:30 عصر

  11. #11

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام

    تشکر از شما .

    بله من آخرین ورژن داخل nuget رو نصب کردم که 7 هستش . من کد تنظیم AutoMapper رو داخل Global گذاشتم متاسفانه هر کار کردم IgnoreUnmapped رو نمی شناسه و قرمزش می کنه . سرچ هم کردم توضیحی نداده بودن . تصویرش رو ضمیمه کردم .

    فکر کنم باید از گفته شما استفاده کنم چون روش دوم واقعا کند هستش و احساس می کنم یک loop شدید می خوره و وقفه زیادی داره به عنوان یک کوئری که ۱۵ تا رکورد داره بر می گردونه ممنون می شم در این رابطه راهنمایی کنید.


    برای Navigation هم طبق گفته شما ef رو update کردم به آخرین ورژن و فودر های bin و obj رو هم حذف کردم ولی متاسفانه زمانی دو مرتبه Include نوشته می شه و لامبادا می نویسم مجدد هیچ عکس العملی از خودش نشون نمی ده


    در کلاس های مدل فرمودید نیاز به سازنده نیست یعنی کد زیر رو حذف کنم از ساختار مدل هام درسته ؟



    public Shop()
    {
    this.ShopCategories = new List<ShopCategory>();
    this.Stones = new List<Stone>();
    }




    عذر خواهی می کنم این مشکل من به درازا کشیده

    ممنون از شما
    عکس های ضمیمه عکس های ضمیمه

  12. #12
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    این کلاس Extenssion را استفاده کتید

    public static class MapperExtensions
    {
    private static void IgnoreUnmappedProperties(TypeMap map, IMappingExpression expr)
    {
    foreach (string propName in map.GetUnmappedPropertyNames())
    {
    if (map.SourceType.GetProperty(propName) != null)
    {
    expr.ForSourceMember(propName, opt => opt.Ignore());
    }
    if (map.DestinationType.GetProperty(propName) != null)
    {
    expr.ForMember(propName, opt => opt.Ignore());
    }
    }
    }

    public static void IgnoreUnmapped(this IProfileExpression profile)
    {
    profile.ForAllMaps(IgnoreUnmappedProperties);
    }

    public static void IgnoreUnmapped(this IProfileExpression profile, Func<TypeMap, bool> filter)
    {
    profile.ForAllMaps((map, expr) =>
    {
    if (filter(map))
    {
    IgnoreUnmappedProperties(map, expr);
    }
    });
    }

    public static void IgnoreUnmapped(this IProfileExpression profile, Type src, Type dest)
    {
    profile.IgnoreUnmapped((TypeMap map) => map.SourceType == src && map.DestinationType == dest);
    }

    public static void IgnoreUnmapped<TSrc, TDest>(this IProfileExpression profile)
    {
    profile.IgnoreUnmapped(typeof(TSrc), typeof(TDest));
    }
    }

    کانفیگ Automapper هست و بار ورژن 7.1.1

    Mapper.Initialize(cfg => {
    cfg.CreateMap<Personnel, PersonnelViewModel>();
    cfg.IgnoreUnmapped();
    });


    برای اعمال lazy loading خودکار وقتی کالکشن های کلاس poco بصورت virtual هستند نیازی به سازنده ی کلاس ها ندارید

    متدinclude در فضای نام System.Data.Entity هست و اگر رفرنس داده باشید نباید خطا بدهد

  13. #13

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام

    وقت بخیر


    طبق گفته های شما الان هیچ خطایی نیست و Include هم با اضافه کردن System.Data.Entity حل شد و با اضافه کردم Extenssion هم IgnoreUnmapped حل شد . الان کد من به شکل زیر شده :


    public List<ShopDemoViewModel> Get()
    {
    var db = new ApplicationDbContext();
    var li = Mapper.Map<List<ShopDemoViewModel>>(db.Shops.Inclu de(x => x.ShopCategories));
    return li;
    }




    الان کد هیچ خطایی نداره و ۵ تا رکورد هم بر می گردونه که به تعداد رکورد های Shop در دیتابیس هستند اما مقدار ها null هستند و خروجی مثل تصویر ضمیمه شده هست . هر چی بالا و پایین کردم مشکل حل نشد .

    ممنون می شم راهنمایی کنید

    تشکر
    عکس های ضمیمه عکس های ضمیمه
    • نوع فایل: jpg res.jpg‏ (27.9 کیلوبایت, 35 دیدار)

  14. #14
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    مشکل از کانفیگ در استارت آپ هست
    تنظیمات به صورت زیر انجام بدید



    Mapper.Initialize(cfg => {
    cfg.IgnoreUnmapped();
    cfg.AddProfile<ShopProfile>();

    });


    Mapper.AssertConfigurationIsValid();



  15. #15

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام و احترام


    الان تنظیمان در Globax من دقیقا به این شکل هست :



    Mapper.Initialize(cfg => {
    cfg.IgnoreUnmapped();
    cfg.AddProfile<ShopProfile>();
    });
    Mapper.AssertConfigurationIsValid();




    ولی همچنان مقادیر داخلی رو null بر می گردونه . کلا توی این پیاده سازی من خوردم به موارد عجیب .

    ممنون می شم اگر نکته ای برای تصحیح هست بفرمایید انجام بدم

    تشکر

  16. #16
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام

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

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

    Mapper.Initialize(cfg => {
    cfg.CreateMap<model, ShopDemoViewModel>();
    cfg.IgnoreUnmapped();
    });

  17. #17

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام

    تشکر از شما برای این پاسخ های زیادی که وقت گذاشتید و دادید . بله Model من در یک Class library جداگانه بود . و تنظیمات رو داخل Globax گذاشتم حل شد و الان نتیجه کاملا درسته .

    فقط برای اینکه ذهنم روشن تر بشه سه سوال روندی دارم خدمتتون :

    ۱ - سریعترین کوئری که برای یک موجودیت با دو رابطه چند به چند می شه نوشت همین هست ؟ چون وب سرویس هست خیلی سرعت کوئری برام مهمه . هیچ بهینه سازی می تونم بکنم ؟

    ۲ - راه دیگه ای وجود نداره که تنظیمان Map رو که الان اوردم داخل globax بشه داخل یک کلاس مثل همون Profile انجام داد ؟ چون اگه موارد زیاد بشن یکم شلوغ می شه این فایل

    ۳ - هر نکته ای در رابطه با بهینه سازی و سرعت و همچنین کیفیت یک سناریو این مدلی هست ممنون می شم بهم بگید

    با تشکر و احترام

  18. #18
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    یک پروفایلر بکار ببرید و چند روش کوئری چند به چند که در اول تاپیک گفتم تست بزنید بینید کوئری تون چقدر کارایی دارد

    بهترینش همین هست

    var shops = db.Shops.Include("ShopCategories").ToList();


    در ضمن وقتی در کوئری چند به چند بر روی مثلا db.shops کوئر ی میزنید دیگر نیاز به Include("Stones") نیست
    چون شما به خود مدل دسترسی مستقیم دارید

    جهت بکارگیری کلاس پروفایل میتونید کلاس های پروفایل را انتقال بدید به پروژه ای که استارت اپ هست و مشکل حل خواهد شد
    میتونید از قابلیت scan ابزاری مثل Structuremap هم برای کانفیگ Automapper استفاده کنید تا کل سولوشن شما اسکن شده و مشکل اینکه مدل هاتون در یک پروژه و ویومدل ها در پروژه ی دیگه هست حل بشه

    روش های دیگری هم برای استفاده از Automapper هست مثلا بکارگیری IMapperConfigurationExpression که خودش بحث جدا دارد و خیلی بهتر از کلاسهای پروفایل هست

    بکارگیری automapper در تمام کوئری هاتون حتمن فراموش نکنید در کارایی و سرعت تاثیر دارد

    البته میتونید کوئری هایی که سرعت بالاتری نیاز دارید بضورت استورد پراسیجر در دیتابیس اسکیول سرور تعریف کنید و در ef صدا بزنید

  19. #19

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    ممنون از راهنماییتون .


    کوئری نهایی که نوشتم و صفحه بندی هم داره به این شکل هست که به درستی اجرا می شه :



    var shopMainQuery =
    db.Shops.Include(x=>x.ShopCategories).Include(x=>x .Stones)
    .OrderByDescending(x => x.Id)
    .ThenBy(x => x.Rate).ToList();


    var storeList = Mapper.Map<List<ShopDataListViewModel>>(shopMainQu ery.Skip(skip).Take(numberPerPage));




    نظرتون رو می فرمایید ؟ درست انجامش دادم ؟ متغییر های paging رو نذاشتم که شلوغ نشه .


    فقط یک مشکلی هم هست من یک CityName دارم که با کد زیر Map کردم که بین Shop و City هم Navigaton هست ولی نام شهر رو بر نمی گردونه توی حالت لیست که از همین ساختار استفاده می کنم مشکلی نیست . اگر در این رابطه هم بفرمایید چیکار باید بکنم ممنون می شم .


    .ForMember(dest => dest.CityName, opt => opt.MapFrom(src => src.City.Name))




    یک رابطه یک به چند هست که با Icollection بحث Navigation رو دادم و Fluent هم طبق اصول و با Navigation هست . نمی دونم چرا نمی آره اسم شهر رو .


    تشکر از شما

  20. #20

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام مجدد

    این مشکل آخر که نام شهر نمی اومد رو من .Include(x=>x.City) گذاشتم مشکل حل شد و نام شهر رو هم می آره .

    سوالم اینه که برای رابطه های یک به چند هم باید Include انجام بشه ؟ چون قبلا برای نمایش لیست ها اطلاعات رو روی Navigation می اورد و مشکلی نبود

    تشکر

  21. #21

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    جسارتا من الان خواستم نمایش یک فروشگاه رو هم پیاده کنم مجبور شدم برای برگرداندن نام شهر به شکل زیر عمل کنم :


    var shopQuery = db.Shops.Include(x => x.City).FirstOrDefault(x=>x.Id==id);
    var storeList = Mapper.Map<ShopDataListViewModel>(shopQuery);



    مقادیر categories و stone رو اتوماتیک می آره و Map می کنه با نام شهر مشکل داره


    با تشکر
    [COLOR=inherit !important]


    [/COLOR]

  22. #22
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    به دو صورت به فیلدهای ناوبری دسترسی داریم یکی lazy loading یا واکشی با تاخیر که همون روش قبلی شماست و دیگری eager loading که با include انجام میشه


    lazy loading : فرض کنید در سایت کاربر بر روی یک کالا کلیک کرده و مشخصات جدول parent باید به او نشان داده شود در این جور کوئری ها که بصورتlazy یا با تاخیر هست شما به ظاهر یک دستور ساده دارید ولی در واقع به محض کلیک کاربر برای نمایش جدول parent یا فیلدهای ناوبری مجددا یک کوئری دیگر صادر میشود
    این جور دستورات در هنگام کار با کالکشن مانند یک بمب افکن هست که کوئری به سمت دیتابیس صادر میشود
    مثلا فرض کنید یک جدول کالا دارید و هر کالا یک فیلد ناوبری از جدول category دارد و مد نظر شماست که یک گالری بسازید وقتی یک کوئری صادر میکنید و بدون include هست این کوئری باید تمام کالا ها همراه با cat مربوطه را در یک جدول نشان دهد گالری شما نشان داده میشود ولی : کافی است کمی به پس زمینه نگاه کنید به ازای هر رکورد navigation یک کوئری صادر میشود و این یک فاجعه هست

    برای حل این مشل از eager loading استفاده میشود و مشهور است به کوئری در لحظه
    و فقط یک کوئری همراه با جوین های مربوطه گالری شما نشون داده میشود

    الان هم تا زود هست کوئری های نیازمند به eager loading را پیدا کنید

  23. #23
    کاربر دائمی آواتار ali_md110
    تاریخ عضویت
    فروردین 1385
    محل زندگی
    شیراز
    پست
    1,181

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    Automapper متدی دارد بنام ProjectTo جهت LinqToObject هست و اگر شما در کوئری هاتون Include هم بکار نبرید بصورت هوشمند Include یا همون eager loading های مورد نیاز را برقرار میکند
    ولی وقتی از ProjectTo بهره نمیبریم مانند مثالهای قبلی شما , باید صراحتا تمام include ها را برقرار کرد
    در اینجا include stone یا include cityهم اضافه کنید تا lazy loading نشود
    در ضمن کلید خارجی مانند cityId را از نوع short بکار نبرید همون int استفاده کنید سازگارتر هست

  24. #24

    نقل قول: نوشتن کوئری با مقادیر رابطه های چند به چند

    سلام

    بی نهایت از توضیحات شما ممنونم . الان روشن شدم که داستان چی هستش .

    خیلی خیلی ممنون که این همه وقت گذاشتید در طی این چند روز گذشته .

    تشکر و احترام

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

  1. مبتدی: کوئری با ارسال پارامتر از ویو به کنترلر
    نوشته شده توسط آنتریوم در بخش ASP.NET MVC
    پاسخ: 6
    آخرین پست: چهارشنبه 19 تیر 1392, 10:23 صبح
  2. سوال: ساختن کوئری با انتخاب فیلد های دیتابیس
    نوشته شده توسط monire.6767 در بخش ASP.NET Web Forms
    پاسخ: 0
    آخرین پست: سه شنبه 24 اردیبهشت 1392, 08:49 صبح
  3. مشکل با نوشتن کوئری Like برای داده شامل کاراکتر %
    نوشته شده توسط bita_naz در بخش C#‎‎
    پاسخ: 1
    آخرین پست: دوشنبه 26 تیر 1391, 14:02 عصر
  4. یک کوئری با چند فرم
    نوشته شده توسط haddadi2 در بخش Access
    پاسخ: 1
    آخرین پست: شنبه 18 مهر 1388, 15:21 عصر
  5. پاسخ: 1
    آخرین پست: جمعه 26 تیر 1388, 08:52 صبح

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

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