It seems Linq2sql doesn't know how to construct the TSQL while you transform linq2sql object into domain object with constructors. Such as:
from c in db.Companies
select new Company (c.ID, c.Name, c.Location).Where(x => x.Name =="Roy");
But when using settable attributes, it will be OK.
from c in db.Companies
select new Company { ID = c.ID, Name = c.Name, Location = c.Location }.Where(x => x.Name =="Roy");
I don't want to allow those attributes to be settable. How can I achieve this? And can anybody provide food for thought on how linq 2 sql is translated into TSQL? Thanks in advance!
It's probably to do with the way L2S parses the expressions - it can parse the object initialiser expression, but not the constructor expression. Basically, the way L2S works is to parse the linq expressions the way any LINQ provider does and then convert the result into SQL.
You could achieve what you'd like by converting it into an IEnumerable first, as then you'll be free to use LINQ to Objects. In the example you gave this is trivial, but let's generalise to a case with a more complex where clause:
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);
The first query is incorrect because the from statement will return a collection of company entities. To get only 1 company you would need to change the first statement to:
Company c = (from c in db.Companies where c.ID = someId select c).First();
The second statement does the where statement implicitly.
I suggest you run SQL Profiler while executing the second query to see what is actually being used as TSQL statement.
It cannot translate a query involving a constructor, because it doesn't know what said constructor is supposed to do. It has field mappings for properties, but your constructor could do absolutely anything - why should it try to second-guess that?
It's not clear what the purpose of making the properties read-only would be for L2S entity classes anyway - it is trivially circumvented by deleting the object and re-creating a new one with the same primary key but new property values.
来源:https://stackoverflow.com/questions/1397394/how-linq-2-sql-is-translated-to-tsql