我在这个linq表达式中有这个错误:
var naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select new Payments
(
nalTmp.Dziecko.Imie,
nalTmp.Dziecko.Nazwisko,
nalTmp.Miesiace.Nazwa,
nalTmp.Kwota,
nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
nalTmp.DataRozliczenia,
nalTmp.TerminPlatnosci
)).ToList();
任何想法如何解决这个问题?我尝试使用表达式的任意组合......:/
答案 0 :(得分:114)
没有关于“付款”的更多信息,这没有多大帮助,但假设您要创建Payments对象并根据列值设置其某些属性:
var naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select new Payments
{
Imie = nalTmp.Dziecko.Imie,
Nazwisko = nalTmp.Dziecko.Nazwisko,
Nazwa= nalTmp.Miesiace.Nazwa,
Kwota = nalTmp.Kwota,
NazwaRodzajuOplaty = nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
NazwaTypuOplaty = nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
DataRozliczenia = nalTmp.DataRozliczenia,
TerminPlatnosci = nalTmp.TerminPlatnosci,
}).ToList();
答案 1 :(得分:107)
如果您仍想使用构造函数进行初始化而不是属性(有时需要此行为用于初始化),请通过调用ToList()
或ToArray()
枚举查询,然后使用{{1 }}。因此,它将使用LINQ to Collections,并且无法使用Select(…)
中的参数调用构造函数的限制将消失。
所以你的代码应该是这样的:
Select(…)
答案 2 :(得分:46)
我自己刚刚遇到此错误,我想我会补充一点,如果Payment
类型是struct
,您也会遇到相同的错误,因为struct
类型不支持无参数构造
在这种情况下,将Payment
转换为类并使用对象初始值设定语法将解决此问题。
答案 3 :(得分:17)
如果你像我一样,并且不想为你正在构建的每个查询填充你的属性,还有另一种方法可以解决这个问题。
var query = from orderDetail in context.OrderDetails
join order in context.Orders on order.OrderId equals orderDetail.orderId
select new { order, orderDetail };
此时您有一个包含匿名对象的IQueryable。如果要使用构造函数填充自定义对象,可以执行以下操作:
return query.ToList().Select(r => new OrderDetails(r.order, r.orderDetail));
现在,您的自定义对象(将两个对象作为参数)可以根据需要填充您的属性。
答案 4 :(得分:8)
首先,我会避免使用
解决方案from ....
select new Payments
{
Imie = nalTmp.Dziecko.Imie,
....
}
这需要一个空的构造函数并忽略封装,所以你说新的Payments()是没有任何数据的有效付款,而是该对象必须至少有一个值,可能还有其他必需字段,具体取决于你的域。
最好有一个必需字段的构造函数,但只带来所需的数据:
from ....
select new
{
Imie = nalTmp.Dziecko.Imie,
Nazwisko = nalTmp.Dziecko.Nazwisko
....
}
.ToList() // Here comes transfer to LINQ to Collections.
.Select(nalImp => new Payments
(
nalTmp.Imie,//assume this is a required field
...........
)
{
Nazwisko = nalTmp.Nazwisko //optional field
})
.ToList();
答案 5 :(得分:2)
您可以尝试执行相同操作,但使用扩展方法。数据库使用的提供者是什么?
var naleznosci = db.Naleznosci
.Where<TSource>(nalTmp => nalTmp.idDziecko == idDziec)
.Select<TSource, TResult>(
delegate(TSource nalTmp) { return new Payments
(
nalTmp.Dziecko.Imie,
nalTmp.Dziecko.Nazwisko,
nalTmp.Miesiace.Nazwa,
nalTmp.Kwota,
nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
nalTmp.DataRozliczenia,
nalTmp.TerminPlatnosci
); })
.ToList();
答案 6 :(得分:2)
在localhost/project/path/to/xampp/path/to/project/uploads/documents
声明之前ToList()
只需DbSet
..
实际的Select
被保存为查询,但尚未完成。
在调用DbSet
之后,您正在使用对象,然后您可以在查询中使用非默认构造函数。
不是最有效的使用时间方式,但它是小集合的选项。
答案 7 :(得分:1)
var naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select new Payments()
{
Dziecko.Imie,
Dziecko.Nazwisko,
Miesiace.Nazwa,
Kwota,
RodzajeOplat.NazwaRodzajuOplaty,
RodzajeOplat.TypyOplat.NazwaTypuOplaty,
DataRozliczenia,
TerminPlatnosci
}).ToList();
这将使用无参数构造函数新建您的Payment对象,然后初始化大括号{ }
答案 8 :(得分:1)
除了上述方法之外,您还可以将其解析为Enumerable集合,如下所示:
(from x in table
....
).AsEnumerable()
.Select(x => ...)
这还有一个额外的好处,就是在构建匿名对象时可以简化生活,如下所示:
(from x in tableName
select x.obj)
.Where(x => x.id != null)
.AsEnumerable()
.Select(x => new {
objectOne = new ObjectName(x.property1, x.property2),
parentObj = x
})
.ToList();
但是,请记住,将集合解析为Enumerable会将其拉入内存,因此可能会占用大量资源!这里应该谨慎使用。
答案 9 :(得分:1)
此外,如果要使用具有多个对象的构造函数进行初始化,如果Linq没有返回任何值,则可能会出错。
所以你可能想做这样的事情:
(from x in table_1
join y in table_2
on x.id equals y.id
select new {
val1 = x,
val2 = y
})
.DefaultIfEmpty()
.ToList()
.Select(a => new Val_Constructor(a.val1 != null ? a.val1 : new Val_1_Constructor(),
a.val2 != null ? a.val2 : new Val_2_Constructor()))
.ToList();
答案 10 :(得分:1)
很抱歉迟到了,但是在找到this之后,我认为这应该是共享的,因为它是我能找到的最干净,最快速且最节省内存的实现。
根据你的例子,你写道:
public static IQueryable<Payments> ToPayments(this IQueryable<Naleznosci> source)
{
Expression<Func<Naleznosci, Payments>> createPayments = naleznosci => new Payments
{
Imie = source.Dziecko.Imie,
Nazwisko = source.Dziecko.Nazwisko,
Nazwa= source.Miesiace.Nazwa,
Kwota = source.Kwota,
NazwaRodzajuOplaty = source.RodzajeOplat.NazwaRodzajuOplaty,
NazwaTypuOplaty = source.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
DataRozliczenia = source.DataRozliczenia,
TerminPlatnosci = source.TerminPlatnosci,
};
return source.Select(createPayments);
}
这里的巨大优势(正如Damien Guard在链接评论中指出的那样)是:
var foo = createPayments(bar);
使用,也可以通过myIQueryable.ToPayments()使用。答案 11 :(得分:1)
我今天遇到了同样的问题,我的解决方案与Yoda列出的类似,但只能使用流利的语法。
使我的解决方案适应您的代码: 我将以下静态方法添加到对象类
var naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select new Payments.Initializer());
然后将基本查询更新为以下内容:
/// <summary>
/// use this instead of a parameritized constructor when you need support
/// for LINQ to entities (query syntax only)
/// </summary>
/// <returns></returns>
public static IQueryable<Payments> Initializer(this IQueryable<Naleznosci> source)
{
return source.Select(
n => new Payments
{
Imie = n.Dziecko.Imie,
Nazwisko = n.Dziecko.Nazwisko,
Nazwa = n.Miesiace.Nazwa,
Kwota = n.Kwota,
NazwaRodzajuOplaty = n.RodzajeOplat.NazwaRodzajuOplaty,
NazwaTypuOplaty = n.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
DataRozliczenia = n.DataRozliczenia,
TerminPlatnosc = n.TerminPlatnosci
};
}
这在逻辑上等同于James Manning的解决方案,其优点是可以将成员初始化的膨胀推向类/数据传输对象
注意:最初我使用的是更具描述性的名称&#34; Initializer&#34; 但在回顾我是如何使用它之后,我发现&#34; Initilizer&#34;足够了(至少对我而言)。
最后注意事项:
在提出这个解决方案之后,我原本以为共享相同的代码并使其适用于Query语法也很简单。我不再相信是这样的。我认为如果你想能够使用这种类型的速记构造,你需要一个方法,如上所述,每个(查询,流畅)流畅,可以存在于对象类本身。
对于查询语法,将需要扩展方法(或正在使用的基类之外的某些方法)。 (因为查询语法想要操作IQueryable而不是T)
以下是我用来最终使其用于查询语法的示例。 (尤达已经钉了这个,但我认为用法可能更清楚,因为我最初没有得到它)
var naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select nalTmp).Initializer().ToList();
和用法
{{1}}
答案 12 :(得分:0)
尽管回答晚了,它仍然可以帮助陷入困境的人。由于LINQ to实体不支持无参数对象构造。但是, IEnumerable 的投影方法。
因此,在选择之前,只需使用以下代码即可将 IQueryable 转换为 IEnumerable :
var result = myContext.SomeModelClass.AsEnumerable().Select(m => m.ToString());
它将正常工作。但是,它当然会失去本机查询的好处。
答案 13 :(得分:0)
IQueryable<SqlResult> naleznosci = (from nalTmp in db.Naleznosci
where nalTmp.idDziecko == idDziec
select new Payments
{
Imie = nalTmp.Dziecko.Imie,
Nazwisko = nalTmp.Dziecko.Nazwisko,
Nazwa= nalTmp.Miesiace.Nazwa,
Kwota = nalTmp.Kwota,
NazwaRodzajuOplaty = nalTmp.RodzajeOplat.NazwaRodzajuOplaty,
NazwaTypuOplaty = nalTmp.RodzajeOplat.TypyOplat.NazwaTypuOplaty,
DataRozliczenia = nalTmp.DataRozliczenia,
TerminPlatnosci = nalTmp.TerminPlatnosci,
});
Repeater1.DataSource = naleznosci.ToList();
Repeater1.DataBind();
public class SqlResult
{
public string Imie { get; set; }
public string Nazwisko { get; set; }
...
}