rohmos

Convert Lambda Expression

با سلام .

فرض کنید دو کلاس با پراپرتی های مشابه هم داریم.

 public class Class1
    {
        public Class1()
        {

        }
        public byte ID { get; set; }
        public string Name { get; set; }
    }

و

 public class Class2
    {
        public Class2()
        {

        }
        public byte ID { get; set; }
        public string Name { get; set; }
    }


که اولی یک DBSet در EF و دومی یک تابع دقیقا مشابه آن در لایه BLL.

حال در لایه BLL یک تایع میخواهم بنویسم که یک Lambda Expression دریافت کند و نتیجه را باتوجه به DBSet کلاس 1 برگرداند. مثل تابع زیر:


 public static Class2 GetData(Expression<><>> input)
        {
            Class2 result =new Class2();
            using (DBDataContext odb=new DBDataContext())
            {
                result=odb.Class1s.Single(input) //Error*****
            }
            return result; 
        }


اما عبارت input بر اساس Class2 میباشد و هنگام اعمال بر Class1 با خطا روبرو میشوم. چطور میتوانم عین همان عبارت وارد شده به تابع را از نوع Class2 به Class1 jfndg کنم و جستجو را بر DBSet انجام دهم؟


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

BLL.GetData(c=>c.ID==0);




این سوال 1 پاسخ دارد.
لذت یادگیری با توسینسو
به عنوان شخصی که مدت هاست از سایت توسینسو استفاده می کنم باید بگم که واقعاً یکی از بهترین مرجع ها برای ارتقاء دانش شخصی هست. دوره های سایت، راهکارها و مطالب، همگی عالی هستند.
حسین احمدی

سلام، وقت بخیر

دقیقاً متوجه نشدم قصد انجام چه کاری رو دارید؟ می خواید از روی کلاس اول، کلاس دوم رو با مقادیر مشابه ایجاد کنید؟ یعنی یک کپی از کلاس اول بر اساس کلاس دوم؟

لطفاً سوال خود را در انجمن مطرح کنید، به سوالات در پیام خصوصی پاسخ داده نخواهد شد
rohmos

سلام . ببخشید منظورتون از انجمن کجاست؟ من متوجه نشدم کجا باید سوالمو بپرسم!!

rohmos

ببینید استاد احمدی . اصلا مشکل من اینه.


من یک برنامه چند لایه دارم مینویسم که بانک اطلاعاتی اون بر اساس  entity faramework Code first هستش حالا میخواهم مطلقا هیچ ارتباطی بین لایه presentation و data Access نباشه. برای همین غیر از لایه bussiness logic یک لایه دیگه هم نوشتم که دقیقا کپی کلاسها و پراپرتی های توی لایه data access منه. و منطق من اینه که اطلاعات از لایه presentation توسط لایه چهارم که اسمش را data traslation گذاشتم به لایه bussiness logic منتقل میشه و اونجا بر اساس اطلاعات دریافتی تجزیه و تحلیل و داده مربوط از طریق لایه data access دریافت و مجدد به شکل یه شیی از کلاس data traslation به لایه presentation برگشت داده میشه. تا حدودی هم موفق بودم تا اینکه یک عبارت لامبدا را خواستم در لایه presentation برای یک تابع موجود در لایه presentation بنویسم. حالا مشکل اینجاست که عبارت لامبدای من بر اساس data traslation است و امکان تبدیل عین همان عبارت را در لایه bussiness logic به یک عبارت لامبدا برای لایه data access خود ندارم. ممکن است کمک کنید.


نمیدانم توانستم درست مطلب را منتقل کنم یا نه. اما اگر راه حلی وجود دارد یا منطق دیگری برای لایه بندی که راحتتر باشد وجود دارد ممنون میشوم که کمک کنید.

حسین احمدی

مفهوم لایه بندی و کلاً معماری نرم افزار طوری هست که روش های مختلفی برای پیاده سازی وجود داره. به طور کلی لایه بندی برای نرم افزار متوسط به پایین الزامی نیست و دلیل منطقی هم برای لایه بندی وجود نداره، برای مثال، خیلی ها از Repository Pattern استفاده می کنن، اما من داخل کارهام برای مواردی که میخوام میام یک Extension Method برای DbSet می نویسیم که همون حالت Repository رو برای من شبه سازی کنه.

اما در مورد کاری که شما می خوایید انجام بدید، اگر درست متوجه شده باشم، شما یه لایه Data Access داری و میخوای اطلاعات بین Data Access و Business Object بوسیله خود Entity ها انجام نشه و یک کپی از کلاس ایجاد بشه.

شما باید برای اینکار DTO یا همون Data Transafer Object رو تعریف کنی، یک object خیلی ساده که مبتنی بر entity هست بدون Navigation ها یا مدلی هست که خروجی دیتا بر اساس اون داخل Application استفاده میشه. حالا اگر درست متوجه شده باشم مشکل شما با Expression هایی هست که برای کوئری استفاده می کنی و چون دسترسی مستقیم به entity ها نداری خطا دریافت می کنی. کاری که به نظر من میرسه و می تونی انجام بدی:


فرض کنیم Entity زیر رو داریم:


public class Customer
{
    public long Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection Orders { get; set; }
}


و یک کلاس به صورت زیر برای ارتباط بین لایه ها تعریف کردی:


public class CustomerDTO
{
    public long Id { get; set; }
    public string Name { get; set; }
    public int TotalOrders { get; set; }
}


شما یک Repository تعریف کن به صورت زیر:


public class CustomerRepository : ICustomerRepository
{
    YourDbContext dbContext;
    public CustomerRepository(YourDbContext dbContext)
    {
        this.dbContext = dbContext;
    }
    public IQueryable All
    {
        return dbContext.Customers.Select(c=> new CustomerDTO
        {
            Id = c.Id,
            Name = c.Name,
            Orders = c.Orders.Count
        }).AsQueryable();
    }
}


با کلاس بالا، شما اگر از IoC و DI استفاده کنی، داخل پروژه دسترسی شما به IQueryable~CustomerDTO هست و دیگه دسترسی مستقیم به Entity ها نداری، با این تفاوت که کوئری شما قابلیت گرفتن کوئری مجدد در لایه های پایین تر رو داره (Deffered Query Execution).


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

لطفاً سوال خود را در انجمن مطرح کنید، به سوالات در پیام خصوصی پاسخ داده نخواهد شد
  • انتخاب شده به عنوان جواب توسط 1 نفر
پاسخ شما
برای ارسال پاسخ خود وارد شوید.
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره بهاره می تونی امروز ارزونتر از فردا خرید کنی ....