2010-06-30 3 views
1
Table:Account 
AccountID|AccountName|AccountTypeID|IsActive 
17  |aaaa  |5   |1 
18  |bbbb  |5   |1 
19  |cccc  |5   |1 

Table:AccountAddress 
AddressID|AccountID|CityId 
1734  |17  |2721 
1823  |18  |2721 
1912  |19  |2722 

Table: City 
CityID|StateProvID|CityName 
2721 |28   |ablinne 
2728 |27   |aberdeen 

Table: StateProv 
StateProvID|CountryID|StateProvName 
27   |1  |- 
28   |2  |- 

Table: Country 
CountryID|RegionID|CountryName 
27  |111  |Algena 
28  |112  |Argentina 

Table: RegionID 
RegionID|RegionName 
111  |Africa 
112  |Asia 

SQL QUERY VOICIjointure question dans subsonique

select Account.AccountID,AccountName,CityName,StateProvName,CountryName,RegionName from Account 
join AccountAddress on AccountAddress.AccountID=Account.AccountID 
join City on City.CityID=AccountAddress.CityID 
join StateProv on StateProv.StateProvID=City.StateProvID 
join Country on Country.CountryID=StateProv.CountryID 
join Region on Region.RegionID=Country.RegionID 
where Account.AccountTypeID=5 
and Account.IsActive=1 
and City.CityID=2721 

Je veux convertir ci-dessus requête dans la requête subsonique ... donc j'écrit comme ci-dessous

DataSet accounts = new Select(
        Account.Columns.AccountName, 
        City.Columns.CityName, 
        Country.Columns.CountryName, 
        Region.Columns.RegionName, 
        StateProv.Columns.StateProvName) 
        .From(Account.Schema) 
        .InnerJoin(AccountAddress.Schema) 
        .InnerJoin(City.Schema) 
        .InnerJoin(StateProv.Schema) 
        .InnerJoin(Country.Schema) 
        .InnerJoin(Region.Schema) 
        .Where(Account.Columns.AccountTypeID).IsEqualTo(accountTypeId) 
        .And(Account.Columns.IsActive).IsEqualTo(isActive) 
        .And(City.CityIDColumn).IsEqualTo(cityId) 
        .ExecuteDataSet(); 

il ne fonctionne pas et j'ai reçu l'erreur "Référence d'objet non définie à une instance d'un objet." S'il vous plaît dites-moi comment récupérer les données comme j'aime?

J'utilise la version 2.1 Subsonic et génère la requête SQL comme ci-dessous

SELECT [dbo].[Account].[AccountName], CityName, CountryName, RegionName,StateProvName 
FROM [dbo].[Account] 
INNER JOIN [dbo].[AccountAddress] ON [dbo].[Account].[AccountID] = [dbo].[AccountAddress].[AccountID] 
INNER JOIN [dbo].[City] ON [dbo].[AccountAddress].[CityID] = [dbo].[City].[CityID] 
INNER JOIN [dbo].[StateProv] ON [dbo].[City].[StateProvID] = [dbo].[StateProv].[StateProvID] 
INNER JOIN [dbo].[Country] ON [dbo].[StateProv].[CountryID] = [dbo].[Country].[CountryID] 
INNER JOIN [dbo].[Region] ON [dbo].[Country].[RegionID] = [dbo].[Region].[RegionID] 
WHERE [dbo].[Account].[AccountTypeID] = @AccountTypeID0 
AND [dbo].[Account].[IsActive] = @IsActive1 
AND CityID = @CityID2 

Répondre

1

décomposer en sections distinctes afin que vous puissiez savoir quel objet est nul.

par exemple .:

var q = new Select( 
       Account.Columns.AccountName, 
       City.Columns.CityName, 
       Country.Columns.CountryName, 
       Region.Columns.RegionName, 
       StateProv.Columns.StateProvName) 
       .From(Account.Schema); 
       q = q.InnerJoin(AccountAddress.Schema); 
       q = q.InnerJoin(City.Schema) 
       q = q.InnerJoin(StateProv.Schema) 
       q = q.InnerJoin(Country.Schema) 
       q = q.InnerJoin(Region.Schema) 
       q = q.Where(Account.Columns.AccountTypeID).IsEqualTo(accountTypeId) 
       q = q.And(Account.Columns.IsActive).IsEqualTo(isActive) 
       q = q.And(AccountAddress.CityIDColumn).IsEqualTo(cityId) 
       DataSet accounts = q.ExecuteDataSet(); 
+0

En fait, le dernier, "q = Q.Et vous avez (AccountAddress.CityIDColumn) .IsEqualTo (CityID)" crée le vide. J'ai donc changé pour "q = q.And (City.Columns.CityID) .IsEqualTo (cityId);". Maintenant, je reçois le nom de la colonne "CityID". " Erreur. Que faire maintenant? aidez s'il vous plaît. – Partha

+0

Pouvez-vous mettre à jour votre question pour inclure la valeur de la chaîne s = q.BuildSqlStatement(); ? –

+0

Vous pouvez également avoir besoin de mettre à jour votre version SubSonic, que courez-vous? –

1

une trace de pile serait utile. Il est très étrange que

q = q.And(AccountAddress.CityIDColumn).IsEqualTo(cityId) 

lève une exception.

Votre solution:

q = q.And(City.Columns.CityID).IsEqualTo(cityId); 

ne fonctionne pas parce que City.Columns.CityId renvoie le nom de la colonne comme une chaîne (sans Tablename et le SQL généré ressemble à ceci:

SELECT tableAID 
FROM tableA 
INNER JOIN tableB ON tableA.tableAID = tableB.tableAID 

et le serveur sql ne sait pas si vous souhaitez sélectionner tableA.tableAID ou tableB.tableAID pour qu'il lève l'exception (même dans un outil de requête autonome)

Si vous travaillez avec le

Table.Columns.Something 

struct au lieu de

Table.SomethingColumn 

et plusieurs tables, vous devriez toujours les concaténer avec le Table.Schema.QualifiedName car ils ne sont que chaîne REPRÉSENTATIONS du nom de colonnes.

var result = DB.Select(Table.Schema.QualifiedName + "." + Table.Columns.Something) 
       .From(Table.Schema) 
       .InnerJoin(AnotherTable.Schema) 
       .Where(AnotherTable.Schema.QualifiedName + "." + 
          AnotherTable.Columns.Quantity) 
       .IsEqualTo(1); 
+0

Des trucs utiles ici. –