I'm new to SubSonic and reasonably new to LINQ as well, so I'm just trying to put a little app together.
I've got the templates all sorted and running okay, but I've run into a bit of trouble with this LINQ statement (simplified slightly, the real statement has some other joins but they don't affect this particular problem so I've removed them for brevity):
var addresses = from address in Database.Addresses.All()
select new Address()
{
MyNestedType = new NestedType()
{
Field1 = address.ADDR1
}
};
If I execute this statement I get the error Invalid cast from 'System.String' to 'NestedType'. when I try to enumerate the results.
I'm probably overlooking the obvious but I can't see anywhere that I request such a conversion.
Both Field1 and address.ADDR1 are strings.
Any ideas what I'm doing wrong?
Edit:
I've had another look at this and in an effort to provide more information, I've created a small, complete example using SimpleRepository and an SQLite database that demonstrates the issue. Using SimpleRepository the error I get is different (Sequence contains no elements) but the result is the same. Here's the complete code:
public class DatabaseAddress
{
public int Id { get; set; }
public string Address1 { get; set; }
}
public class Address
{
public NestedType MyNestedType;
}
public class NestedType
{
public string Field1 { get; set; }
}
static class Program
{
[STAThread]
static void Main()
{
var repo = new SimpleRepository("Db", SimpleRepositoryOptions.RunMigrations);
DatabaseAddress address1 = new DatabaseAddress();
address1.Address1 = "Test";
repo.Add(address1);
var all = repo.All<DatabaseAddress>();
var addresses = from address in repo.All<DatabaseAddress>()
select new Address { MyNestedType = new NestedType { Field1 = address.Address1 } };
}
}
In this example, all
contains the object added to the database, but addresses
returns "Sequence contains no elements".
If I use anonymous types instead of concrete types in the select
statement it works.
There's obviously a gap in my knowledge here; any help appreciated.
You have to call ToList(), otherwise the SubSonic provider tries to do something with MyNestedType and it doesn't exist in the database.
var addresses = from address in repo.All<DatabaseAddress>().ToList()
select new Address { MyNestedType = new NestedType { Field1 = address.Address1 } };
Update: It also works if you call ToList afterwards, i.e.:
addresses.ToList().ForEach(address => Console.WriteLine("Address.MyNestedType.Field1 = {0}", address.MyNestedType.Field1));
I guess there is a bug in the SubSonic query provider, because it does work for anonymous types, as you mentioned.
Please see my question and answer here.
Here's how you can test if it is the same issue:
In that sample code you posted, change Field1 in your NestedType to be named Address1. Re-run your sample. If it works, same issue and the fix I answered with in the linked question should solve it for you.
Try this
var nestedTypes= from address in Database.Addresses.All()
select new NestedType()
{
Field1 = address.ADDR1
};
来源:https://stackoverflow.com/questions/3255193/linq-and-subsonic-returning-nested-complex-types