C# LINQ2SQL如何转换为TSQL

C# LINQ2SQL如何转换为TSQL,c#,linq-to-sql,domain-driven-design,linq-to-objects,ddd-repositories,C#,Linq To Sql,Domain Driven Design,Linq To Objects,Ddd Repositories,当您使用构造函数将Linq2sql对象转换为域对象时,Linq2sql似乎不知道如何构造TSQL。例如: from c in db.Companies select new Company (c.ID, c.Name, c.Location).Where(x => x.Name =="Roy"); 但是当使用可设置的属性时,它就可以了 from c in db.Companies select new Company { ID = c.ID, Name = c.Name, Locatio

当您使用构造函数将Linq2sql对象转换为域对象时,Linq2sql似乎不知道如何构造TSQL。例如:

from c in db.Companies
select new Company (c.ID, c.Name, c.Location).Where(x => x.Name =="Roy");
但是当使用可设置的属性时,它就可以了

from c in db.Companies
select new Company { ID = c.ID, Name = c.Name, Location = c.Location }.Where(x => x.Name =="Roy");

我不想让这些属性可以设置。我怎样才能做到这一点?任何人都能提供思考LINQ2SQL如何转换为TSQL的素材吗?提前谢谢

第一个查询不正确,因为from语句将返回公司实体的集合。要仅获得一家公司,您需要将第一条语句更改为:

Company c = (from c in db.Companies where c.ID = someId select c).First();
第二条语句隐式执行where语句


我建议您在执行第二个查询时运行SQL Profiler,查看实际用作TSQL语句的内容。

这可能与L2S解析表达式的方式有关-它可以解析对象初始化器表达式,但不能解析构造函数表达式。基本上,L2S的工作方式是以这种方式解析linq表达式,然后将结果转换为SQL

您可以先将它转换为IEnumerable,这样您就可以自由使用它了。在您给出的示例中,这并不重要,但让我们将其推广到一个更复杂的where子句:

var companyData =
    from c in db.Companies
    where c.Name.StartsWith("Roy")
    select new { c.ID, c.Name, c.Location };

var companies =
    from c in companyData.AsEnumerable()
    select new Company(c.ID, c.Name, c.Location);

它无法转换包含构造函数的查询,因为它不知道该构造函数应该做什么。它有属性的字段映射,但是你的构造函数可以做任何事情——为什么它要去猜测呢


目前还不清楚L2S实体类将属性设置为只读的目的是什么——删除对象并重新创建一个具有相同主键但新属性值的新对象可以很容易地避免这种情况。

您说过Linq2Sql不知道如何在第一次查询中转换为TSQL?Colin,我看不出Roy要求查询返回集合以外的任何内容。他说,他发表的两份声明应该是相等的(我也同意),但事实并非如此。一般来说,新公司(someID,someName,someLocation)应该与新公司{ID=someID,Name=someName,Location=someLoc}互换工作。也就是说,这两个查询都会返回一个公司对象的集合,就像它们应该返回的一样。是的,谢谢。但我认为使用LINQ2对象时,性能会受到影响。ADO Entify框架有这样一个问题吗?不确定为什么您认为会出现性能下降?对象实例化实际上需要几微秒的时间。注意不要落入过早优化的陷阱。在我的应用程序中,我想利用IQueryable的优势。我的意思是,在调用GetAllProducts()之后过滤出结果。例如:GetAllProducts().SingleOrDefault(x=>x.Name==“Microsoft”);如果我使用LINQ2对象,每次调用都会导致构造所有对象。当我们有超过10000种产品时,这难道不是一个性能上的打击吗?在我看来,如果你试图将L2S IQueryables传递到你的数据层边界之外,你会得到各种各样的惊喜,因为SQL查询只在你开始枚举时才执行,这可能发生在另一层。这可能是个人偏好的问题,但我始终更喜欢从数据层返回IEnumerables(即,如果使用该模式,则从存储库返回)。您仍然可以在中传递任意条件以执行。但是在执行查询之后,您可以随意处理它。@Roy我遇到了DDD主体驱动的相同问题。您是如何使参数化构造函数工作的?谢谢,我没有强制l2s实体的属性为只读。我正在强制域对象。我想使用构造函数,因为我想在构造函数中封装一些逻辑,比如验证逻辑。但这似乎使任何linq技术都无法转换查询。