Problem: Ich möchte Code zwischen mehreren Baugruppen freigeben. Dieser gemeinsam genutzte Code muss mit LINQ zu SQL-Map-Klassen funktionieren.LINQ to SQL - Zuordnungsausnahme bei Verwendung von abstrakten Basisklassen
Ich habe das gleiche Problem gefunden gefunden here, aber ich habe auch eine Work-Around gefunden, die ich beunruhigend finde (ich gehe nicht so weit zu sagen "Bug").
Der gesamte folgende Code kann in this solution heruntergeladen werden.
Angesichts dieser Tabelle:
create table Users
(
Id int identity(1,1) not null constraint PK_Users primary key
, Name nvarchar(40) not null
, Email nvarchar(100) not null
)
und diese DBML Mapping:
<Table Name="dbo.Users" Member="Users">
<Type Name="User">
<Column Name="Id" Modifier="Override" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
<Column Name="Name" Modifier="Override" Type="System.String" DbType="NVarChar(40) NOT NULL" CanBeNull="false" />
<Column Name="Email" Modifier="Override" Type="System.String" DbType="NVarChar(100) NOT NULL" CanBeNull="false" />
</Type>
</Table>
ich die folgenden Basisklassen in einer Baugruppe "Shared" erstellt haben:
namespace TestLinq2Sql.Shared
{
public abstract class UserBase
{
public abstract int Id { get; set; }
public abstract string Name { get; set; }
public abstract string Email { get; set; }
}
public abstract class UserBase<TUser> : UserBase where TUser : UserBase
{
public static TUser FindByName_Broken(DataContext db, string name)
{
return db.GetTable<TUser>().FirstOrDefault(u => u.Name == name);
}
public static TUser FindByName_Works(DataContext db, string name)
{
return db.GetTable<TUser>().FirstOrDefault(u => u.Name == name && 1 == 1);
}
public static TUser FindByNameEmail_Works(DataContext db, string name, string email)
{
return db.GetTable<TUser>().FirstOrDefault(u => u.Name == name || u.Email == email);
}
}
}
Diese Klassen werden in einer anderen Assembly "Main" wie folgt referenziert:
namespace TestLinq2Sql
{
partial class User : TestLinq2Sql.Shared.UserBase<User>
{
}
}
Die DBML-Datei befindet sich auch in der "Main" -Assembly.
System.InvalidOperationException: Klasse Mitglied UserBase.Name ist unmapped
Wenn
User.FindByName_Broken(db, "test")
Aufruf, wird eine Ausnahme ausgelöst.
Die anderen beiden statischen Basismethoden funktionieren jedoch.
Darüber hinaus ist die SQL erzeugt durch User.FindByName_Works(db, "test")
Aufruf wird, was in dem gebrochenen Ruf der Hoffnung, wir waren:
SELECT TOP (1) [t0].[Id], [t0].[Name], [t0].[Email]
FROM [dbo].[Users] AS [t0]
WHERE [t0].[Name] = @p0
-- @p0: Input NVarChar (Size = 4; Prec = 0; Scale = 0) [test]
Während ich bin bereit, dies für einzelne Prädikat Abfragen 1 == 1
„Hack“ zu verwenden, gibt es ein besseres Möglichkeit, LINQ mit SQL-fähigem Code in einer base/shared/core Assembly zu teilen?
Es macht eine Abfrage ohne where-Klausel und dann wird die Liste im Speicher gefiltert. Nicht gut für viele Ergebnisse; – Gandarez