PDA

View Full Version : سوال: خطای The entity or complex type '...' cannot be constructed in a LINQ to Entities query



erfan_urchin
پنج شنبه 12 اسفند 1395, 17:41 عصر
سلام
دوستان من میخوام کد زیر رو توی C#‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎ با entity framework بنویسم


select sum(price) from orders group by name
وقتی به صورت عادی کدها رو داخل button_click مینویسم درست اجرا میشه (کد رو به صورت زیر مینویسم و درست هم اجرا میشه)


private void button4_Click(object sender, EventArgs e)
{
var q = database.orders
.GroupBy(a => a.name)
.Select(a => new {id= a.Sum(b => b.price)});
dataGridView1.DataSource = q.ToList();
}



اما وقتی میخوام کد رو داخل یه تابع بنویسم و اون رو فراخوانی کنم به مشکل میخورم (کد رو به صورت زیر مینویسم و بعد از اجرا کردن خطا میده)


//class order
public IEnumerable<order> sum()
{
var q = database.orders
.GroupBy(a => a.name)
.Select(a => new order() { price = a.Sum(b => b.price) });
return q.ToList();
}




// Form1
private void button4_Click(object sender, EventArgs e)
{
order o = new order();
dataGridView1.DataSource = o.SUM();
}


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

ali_md110
پنج شنبه 12 اسفند 1395, 20:08 عصر
.Select(a => new order() { price = a.Sum(b => b.price) });

این قسمت کد اشکال داره و Linq To Entity نمیتونه معادل کدهای اسکیولی تولید بکنه
شما باید از ویومدل مثلا OrderViewModel بجای new order به همراه ابزاری مثل Automapper برای Projecion استفاده کنید.

erfan_urchin
پنج شنبه 12 اسفند 1395, 20:49 عصر
ممنون از پاسختون
من دقیقا همین کاری که شما فرمودین رو انجام دادم
در واقع من دارم با معماری 3 لایه این کار رو انجام میدم
من یک کلاس دارم به اسم orderOperation که به عنوان لایه DAL هستش و تابع زیر رو داخلش نوشتم

public static IEnumerable<order> sum()
{
var q = from r in database.orders
group r by r.name into g
select new order { name = g.Key, sum = g.Sum(m => m.price) };
return q.ToList();
}

یک کلاس هم دارم به نام order که به عنوان لایه Business هستش و پراپرتی ها و تابع زیر رو داخلش نوشتم

public int sum { get; set; }
public int price { get; set; }
public int orderid { get; set; }
public string name { get; set; }

public IEnumerable<order> SUM()
{
return orderoperation.sum();
}

و در نهایت تو لایه presentation هم کد زیر رو مینویسم

private void button4_Click(object sender, EventArgs e)
{
order o = new order();
dataGridView1.DataSource = o.SUM();
}

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

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

Mahmoud.Afrad
پنج شنبه 12 اسفند 1395, 22:53 عصر
اگر اشتباه نکنم کلاس order کلاسی از مدل دیتابیس هست. در اینجا به کلاسی نیاز دارید که برای نمایش استفاده بشه و تاثیری روی مدل دیتابیس نداشته باشه و می بایست با کلاس order متفاوت باشد. پس کلاسی غیر از order ایجاد کنید و نوع متد و کوئری رو اصلاح کنید. (معمولا زمانی که نیاز داشته باشند در select مقداری را new کنند یا بدون نوع در نظر میگیرند یا در صورتی که نیاز به نوع باشد یک کلاس ویومدل ایجاد میکنند)


اما با یک ترفند هم میشه به جواب رسید
کافیه در لایه dal یک متدprivate دیگر ایجاد کنید که توسط متد public فراخوانی شود. متد private رو میتونید به صورت ExtensionMethod دربیارید.
public IEnumerable<order> sum()
{
return GetSumPriceForEachOrderGroup(database.orders);
}

private IEnumerable<order> GetSumPriceForEachOrderGroup(IEnumerable<order> sourceOrders)
{
return sourceOrders
.GroupBy(i => i.Name)
.Select(g => new order() { Name = g.Key, Price = g.Sum(m => m.Price) })
.ToList();
}