我正在尝试用Linda在Linq中编写一些代码。这是我使用lambda的第一个代码,我在更新Record时面临一个问题。 我的代码是:
using (DataClasses1DataContext db = new DataClasses1DataContext())
{
Table<NOTIF_RECIP> NOTIF_RECIP_alias = db.GetTable<NOTIF_RECIP>();
Table<NOTIF_SCHED> NOTIF_SCHED_alias = db.GetTable<NOTIF_SCHED>();
Table<mainframe_replication> mainframe_replication_alias = db.GetTable<mainframe_replication>();
var ids = NOTIF_SCHED_alias.Select(x => x.NOTIF_RPT_ID).ToArray();
foreach (string notif_sched_data in ids)
{
var repljoinmf = mainframe_replication_alias
.Join(NOTIF_RECIP_alias,
mfr => mfr.RPT_ID,
nr => nr.NOTIF_RECIP_ID,
(mfr, nr) => new
{
ReportId=mfr.RPT_ID,
Reportversion=mfr.RPT_VERS,
ReportBytes= mfr.RPT_BYTES.ToString(),
ReportDate=mfr.REPL_DTM.ToString(),
NotifId= mfr.NOTIF_ID,
RecipAdd=nr.NOTIF_RECIP_ADDR
});
foreach(var repljoinmf_data in repljoinmf)
{
//DO STUFF
repljoinmf_data.NotifId = "Changedxyz";
//db.SubmitChanges();
}
}
}
我在repljoinmf_data.NotifId = "Changedxyz";
收到错误
错误说:错误2属性或索引器'AnonymousType#3.NotifId'无法分配 - 它是只读的
有人可以帮助我。我认为这是因为我使用的是匿名的var,但是如何解决这个问题。感谢任何帮助。
由于
答案 0 :(得分:1)
正如错误所示,匿名类实例一经投影就无法修改。
虽然您可以切换到强类型类,然后重新分配成员属性,但是,您有机会将前面的LINQ语句中的所需结果投影到同一个匿名类中:
pointer = malloc(sizeof(*pointer));
编辑,更新不是简单的任务,建议的替代方案
选项#1:投影后具有突变的强类型类
添加一个新类(我已经猜到了一些类型)
sizeof(*pointer)
然后您可以投影到(只需指定类名而不是匿名):
sizeof(struct Data)
然后进行修改:
var repljoinmf = mainframe_replication_alias
.Join(NOTIF_RECIP_alias, mfr => mfr.RPT_ID, nr => nr.NOTIF_RECIP_ID,
(mfr, nr) => new // Anon Class projection
{
ReportId=mfr.RPT_ID,
Reportversion=mfr.RPT_VERS,
ReportBytes= mfr.RPT_BYTES.ToString(),
ReportDate=mfr.REPL_DTM.ToString(),
NotifId= "Changedxyz", // *** No need to mutate this afterwards
RecipAdd=nr.NOTIF_RECIP_ADDR
});
选项#2 - 创建一个执行复杂逻辑的方法(或Func)
由于您似乎已经实现了所有数据,因此可以在属性预测中自由使用复杂函数。任何可用的局部变量(闭包)都可以传递给函数,连接lambda参数public class MyPoco
{
public int ReportId {get; set;}
public string Reportversion {get; set;}
public byte[] ReportBytes {get; set;}
public DateTime ReportDate {get; set;}
public int NotifId {get; set;}
public string RecipAdd {get; set;}
}
例如,编写一个函数来计算(mfr, nr) => new MyPoco // Not anonymous
{
ReportId=mfr.RPT_ID,
...
替换:
foreach(var repljoinmf_data in repljoinmf)
{
repljoinmf_data.NotifId = "SomeNewValue"
然后您可以在原始匿名投影中使用
(mfr, nr)
答案 1 :(得分:1)
匿名类型为immutable
因此无法更改,因此您必须创建新类型
要解决您的问题,您必须创建自己的类型,并在需要进行更新时避免使用匿名类型
你的类型可能看起来像这样
public class ReportInfo
{
public int Id{get; set;}
//the same thing for others properties
}
,您的查询将如下所示
new ReportInfo() {
Id = mfr.RPT_ID,
Reportversion = mfr.RPT_VERS,
ReportBytes = mfr.RPT_BYTES.ToString(),
ReportDate = mfr.REPL_DTM.ToString(),
NotifId = mfr.NOTIF_ID,
RecipAdd = nr.NOTIF_RECIP_ADDR
})
比您可以轻松更新您的财产
foreach(var repljoinmf_data in repljoinmf)
{
//DO STUFF
repljoinmf_data.NotifId = "Changedxyz";
//db.SubmitChanges();
}
有关匿名类型的更多信息
编译器实际上在做什么。当你写这样一行代码时:
var o = new { property1 = expression1, ..., propertyN = expressionN };
编译器推断每个表达式的类型,创建这些推断类型的私有字段,创建 每个字段的公共只读属性,并创建一个接受所有这些属性的构造函数 表达式。构造函数的代码初始化表达式结果中的私有只读字段 传递给它。此外,编译器会覆盖Object的Equals,GetHashCode和ToString 方法并在所有这些方法中生成代码。
答案 2 :(得分:0)
如果您想稍后更改'NotifId',您可以按ID找到记录并更改属性。
示例:
var alias = mainframe_replication_alias.SingleOrDefault(mfr => mfr.NOTIF_ID == repljoinmf_data.NotifId);
if(alias != null)
alias.NOTIF_ID = "Changedxyz";