الاستعلام ينق مع مبلغ قيم الفارغة
-
22-08-2019 - |
سؤال
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Votes
where b.ItemId == v.ItemId
select v.Points).Sum()
}
وحصلت على هذا الاستعلام، ومع ذلك فإنه يفشل إذا لم يتم العثور على الأصوات مع استثناء:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
وأفترض، ذلك لأن مبلغ بإرجاع عدد صحيح وليس كثافة قيم الفارغة، وإعطاء مبلغ من كثافة العمليات؟ كمدخل تعطي إلا نفس الخطأ، وربما يسبب مبلغ workes فقط على [إينتس].
وأي حل جيد لهذا؟
المحلول
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Votes
where b.ItemId == v.ItemId
select v.Points ?? 0).Sum()
}
وتحرير - طيب ماذا عن هذا ... (إطلاق النار مرة أخرى لأنني لا أعرف النموذج الخاص بك ...):
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Votes
where b.ItemId == v.ItemId)
.Sum(v => v.Points)
}
نصائح أخرى
وترغب في استخدام النموذج قيم الفارغة من سوم، وذلك في محاولة صب القيمة الخاصة بك إلى قيم الفارغة:
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Votes
where b.ItemId == v.ItemId
select v.Points).Sum(r => (decimal?) r.Points)
}
ويناقش مشكلتك هنا بمزيد من التفصيل:
<وأ href = "http://weblogs.asp.net/zeeshanhirani/archive/2008/07/15/applying-aggregates-to-empty-collections-causes-exception-in-linq-to-sql. ASPX "يختلط =" noreferrer "> http://weblogs.asp.net/zeeshanhirani/archive/2008/07/15/applying-aggregates-to-empty-collections-causes-exception-in-linq-to-sql. ASPX
وعلى افتراض "v.Points" هو عشري مجرد استخدام ما يلي:
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Votes
where b.ItemId == v.ItemId
select (decimal?) v.Points).Sum() ?? 0
}
إذا كنت لا تحب الصب إلى nullabe عشري هل يمكن أيضا محاولة استخدام LINQ إلى كائنات مع ToList طريقة ()،
وLinqToObjects مجموع جمع الفارغ هو 0، حيث LinqToSql مجموع مجموعة فارغة لاغيا.
ومحاولة للتحقق من ذلك:
var count = db.Cart.Where(c => c.UserName == "Name").Sum(c => (int?)c.Count) ?? 0;
وهكذا، جذر المشكلة هو أن SQL الاستعلام مثل هذا:
SELECT SUM([Votes].[Value])
FROM [dbo].[Votes] AS [Votes]
WHERE 1 = [Votes].[UserId]
ويعود NULL
وللمشكلة بسيطة لكنها فعالة سيكون لتلخيص فقط الأصوات حيث Points.Count> 0، لذلك لست مضطرا ابدا القيم الخالية:
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Votes
where b.ItemId == v.ItemId &&
v.Points.Count > 0
select v.Points).Sum()
}
وفقط لإضافة طريقة أخرى في مزيج:)
Where(q=> q.ItemId == b.ItemId && b.Points.HasValue).Sum(q=>q.Points.Value)
وكان سيناريو مماثل ولكن لم أكن مقارنة حقل إضافي عند تلخيص ...
Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);
وعلى افتراض نقاط هي قائمة Int32، وكيف حول شيء من هذا القبيل:
var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)
وكان لي نفس المشكلة. حلها مع قائمة الاتحاد فارغة:
List<int> emptyPoints = new List<int>() { 0 };
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Votes
where b.ItemId == v.ItemId
select v.Points).Union(emptyPoints).Sum()
}
في حالة من "نقاط" غير صحيح هذا يجب أن تعمل.
وأعتقد أن هذا هو نفس القضية. I حلها. هذا هو بلدي الحل:
var x = (from a in this.db.Pohybs
let sum = (from p in a.Pohybs
where p.PohybTyp.Vydej == true
select p.PocetJednotek).Sum()
where a.IDDil == IDDil && a.PohybTyp.Vydej == false
&& ( ((int?)sum??0) < a.PocetJednotek)
select a);
وآمل أن يكون هذا العون.
(from i in Db.Items
where (from v in Db.Votes
where i.ItemId == v.ItemId
select v.Points).Count() > 0
select new VotedItem
{
ItemId = i.ItemId,
Points = (from v in Db.Items
where i.ItemId == v.ItemId
select v.Points).Sum()
}).Union(from i in Db.Items
where (from v in Db.Votes
where i.ItemId == v.ItemId
select v.Points).Count() == 0
select new VotedItem
{
ItemId = i.ItemId,
Points = 0
}).OrderBy(i => i.Points);
وهذا يعمل، ولكن ليست جميلة جدا أو قابل للقراءة.
وكان لي مشكلة مشابهة، وجاء مع الحل للحصول على كل ما كنت أحاول الخروج من قاعدة البيانات، والقيام العد على تلك، وعندها فقط إذا كان لي أي شيء عاد قيام المبلغ. لم يكن قادرا على الحصول على المدلى بها العمل لسبب بالإرسال لذلك هذا إذا كان أي شخص آخر قد قضايا مماثلة.
ومنها مثلا.
Votes = (from v in Db.Votes
where b.ItemId = v.ItemId
select v)
وثم تحقق لمعرفة ما إذا كنت قد حصلت على أي نتائج حتى لا تحصل عاد لاغية.
If (Votes.Count > 0) Then
Points = Votes.Sum(Function(v) v.Points)
End If
وعلى غرار الأجوبة السابقة، ولكن يمكنك أيضا يلقي نتيجة المبلغ بأكمله إلى نوع قيم الفارغة.
from i in Db.Items
select new VotedItem
{
ItemId = i.ItemId,
Points = (decimal?)((from v in Db.Votes
where b.ItemId == v.ItemId
select v.Points).Sum()) ?? 0
}
ويمكن القول هذا أفضل يناسب ما يحدث في الواقع لكنه لا يملك نفس تأثير المدلى بها في هذه الإجابة .
والفكر وأود أن رمي حل آخر هناك. كان لي مشكلة مشابهة وهذه هي الطريقة التي انتهى بي الأمر حلها:
Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)