Vấn đề: Tôi muốn chia sẻ mã giữa nhiều hội đồng. Mã chia sẻ này sẽ cần phải làm việc với các lớp được ánh xạ LINQ to SQL.LINQ to SQL - ánh xạ ngoại lệ khi sử dụng lớp cơ sở trừu tượng
Tôi đã gặp phải cùng một vấn đề được tìm thấy here, nhưng tôi cũng tìm thấy một công việc xung quanh mà tôi thấy phiền hà (Tôi sẽ không đi xa như vậy để nói "lỗi").
Tất cả các mã sau có thể được tải xuống trong this solution.
Với bảng này:
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
)
và lập bản đồ DBML này:
<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>
tôi đã tạo các lớp cơ sở sau đây trong một lắp ráp "chia sẻ":
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);
}
}
}
Các lớp này được tham chiếu trong một assembly "Main" khác, như sau:
namespace TestLinq2Sql
{
partial class User : TestLinq2Sql.Shared.UserBase<User>
{
}
}
Tệp DBML cũng nằm trong hội đồng "Chính".
Khi gọi User.FindByName_Broken(db, "test")
, một ngoại lệ được ném:
System.InvalidOperationException: Phân loại thành viên UserBase.Name là unmapped.
Tuy nhiên, hai phương thức tĩnh cơ bản khác hoạt động.
Hơn nữa, SQL được tạo ra bằng cách gọi User.FindByName_Works(db, "test")
là những gì chúng tôi đã hy vọng cho trong các cuộc gọi bị hỏng:
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]
Trong khi tôi sẵn sàng để sử dụng này 1 == 1
"hack" cho các truy vấn ngữ duy nhất, là có một tốt hơn cách chia sẻ mã LINQ to SQL-aware trong một assembly cơ bản/chia sẻ/lõi?
Nó làm một truy vấn không có bất kỳ mệnh đề where và sau đó danh sách được lọc trong bộ nhớ. Không tốt cho nhiều kết quả; – Gandarez