C# LINQ To Sql 默认对象实例化过度优化?

标签 c# .net linq

LINQ to SQL 编译器似乎过度优化了内部包含其他类的类的默认类值。

下面是一些说明问题的示例代码:

void Main()
{
    testInitialValueFromDB();
}

void testDefault()
{
    using(DataContext db = new DataContext()) //in my actual code its GEMSDBDataContext where it got created from a .dbml file
    {
        var result = db.GEMSUsers.Take(10).Select(x=> new AllInfo {
            info = new InitialInfo {
                Test1 = x.username.Length
            },
            info2 = new SetAfterInfo {
                Test2 = ""
            }
        }).ToList();

        result[0].info2.Test2 = "Setting afterwards";
    }
        //from now on all the values in result say Setting afterwards

}

void testInitialValueFromDB()
{
    using(DataContext db = new DataContext()) //in my actual code its GEMSDBDataContext where it got created from a .dbml file
    {
        var result = db.GEMSUsers.Take(10).Select(x=> new AllInfo {
            info = new InitialInfo {
                Test1 = x.username.Length
            },
            info2 = new SetAfterInfo {
                Test2 = x.rowguid.ToString()
            }
        }).ToList();


       result[0].info2.Test2 = "Setting afterwards";
    }
    //This actually works and only the first item is changed
}

void testGuid()
{
    using(DataContext db = new DataContext()) //in my actual code its GEMSDBDataContext where it got created from a .dbml file
    {
        var result = db.GEMSUsers.Take(10).Select(x=> new AllInfo {
            info = new InitialInfo {
                Test1 = x.username.Length
            },
            info2 = new SetAfterInfo {
                Test2 = System.Guid.NewGuid().ToString()
            }
        }).ToList();

        //I would expect Test2 to be a new guid everytime but it's always the same, like the class got instantiated only once.
        result[0].info2.Test2 = "Setting afterwards";
        //again this changes for all the elements in the list
    }
}

public class AllInfo
{
    public InitialInfo info {get; set;}
    public SetAfterInfo info2 {get; set;}
}

public class InitialInfo
{
    public int Test1 {get; set;}
}

public class SetAfterInfo
{
    public string Test2 {get; set;}
}

现在,如果您调用 testDefault() 或 testGuid(),似乎只初始化一次 SetAfterInfo,如果我更改任何元素的 Test2 属性,它会在列表中的每个项目中更新。

我遇到这个错误是因为我必须运行一个查询,但我必须以一种无法在 SQL 中表示的方式将属性设置为一个值,所以我在代码中调用 ToList() 之后才这样做.

唯一可行的方法是从数据库初始化 Test2,在这种情况下输出是预期的。

我只是好奇这是否是 LINQ to SQL 编译器中的合法错误。

更多信息:

.NET 框架 4.5 SQL 服务器 2012

最佳答案

从偏离规范的意义上讲,这不是错误,因为没有记录此查询的行为。 L2S(和 EF)没有记录很多事情。

但从某种意义上说,这是一个错误,团队可能会同意应该对此进行更改。

不幸的是,L2S 团队已不复存在。产品被放弃。不要指望修复。

作为变通方法引入人为依赖:

        info2 = new SetAfterInfo {
            Test2 = someStringColumn.Substring(0, 0) //empty string
        }

L2S 将不再认为 info2 的初始值设定项是常量。本着这种精神,您可以使用任何其他人工依赖。例如,您可以将一列分配给虚拟属性。

关于C# LINQ To Sql 默认对象实例化过度优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29708777/

相关文章:

c# - 在我们的.net项目中更改MSBuild工具集(ToolsVersion)有什么缺点?

c# - 将较小的数组插入较大的数组,反之亦然

c# - 初始化查找<int, string>

c# - 将 C# 泛型类型作为参数传递

c# - 基于文本树创建 XML

.net - LINQ:如何为查询结果四舍五入小数值?

c# - 无法读取隐藏字段

c# - 在 ASP.NET Core 中实现 "JSON Merge Patch"- 区分 null 和未定义属性的最佳方法

c# - "ignoring"P/Invoke 在 Mono 上运行时

c# - 为什么 WPF DataGrid 的垂直滚动太大?