LINQ to SQL的 - 映射的异常使用抽象基类时(LINQ to SQL - mapping

2019-06-23 17:40发布

问题:我想多个组件之间共享代码。 这种共享的代码将需要使用LINQ合作,SQL映射类。

我遇到同样的问题找到这里 ,但我也发现了一个变通办法,我觉得麻烦(我不会那么远,说“错误”)。

所有下面的代码可以在下载该解决方案 。

鉴于此表:

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
)

这DBML映射:

<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>

我已经创建了下面的基类中的一个组件“共享”:

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);
        }
    }
}

这些类是在另一个组件“主”引用,就像这样:

namespace TestLinq2Sql
{
    partial class User : TestLinq2Sql.Shared.UserBase<User>
    {

    }
}

该DBML文件位于“主”装配,以及。

当调用User.FindByName_Broken(db, "test")抛出一个异常:

System.InvalidOperationException:类构件UserBase.Name是未映射的。

然而,另外两个基地的静态方法的工作。

此外,通过调用生成的SQL User.FindByName_Works(db, "test")是我们所希望看到的在破碎的呼叫:

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]

虽然我愿意用这1 == 1 “黑客”对单个预测查询,是否有对基/共享/核心组件共享的LINQ to SQL数据的相关代码更好的办法?

Answer 1:

我也遇到这个问题很多次,在过去,因为我们在我们在我们公司使用的框架类似的架构。 您可能已经注意到,如果你使用的声明样式LINQ查询,你会不会遇到这个问题。 例如,下面的代码将工作:

return (from i in db.GetTable<TUser>() where i.Name = "Something").FirstOrDefault();

然而,由于我们使用的是动态过滤器表达式,我们不能使用这种方法。 替代解决方案是使用这样的:

return db.GetTable<TUser>().Select(i => i).Where(i => i.Name == "Something").SingleOrDefault();

该解决方案解决了我们的问题,因为我们可以注入一个“选择(I => I)”几乎所有的表达式的开始。 这将导致发动机的Linq不看的映射的基类,将迫使它来看看实际的实体类,并找到映射。

希望能帮助到你



Answer 2:

尝试包括OfType之前Where子句

return _dbContext.GetTable<T>().OfType<T>().Where(expression).ToList();



Answer 3:

我有运气定义数据类的共享组件,在许多组件与许多组件数据类映射到一个共享的合同消费它们。 使用你的例子命名空间,把一个自定义的DataContext和共享数据类中TestLinq2Sql.Shared:

namespace TestLinq2Sql.Shared
{
    public class SharedContext : DataContext
    {
        public Table<User> Users;
        public SharedContext (string connectionString) : base(connectionString) { }
    }

    [Table(Name = "Users")]
    public class User
    {
        [Column(DbType = "Int NOT NULL IDENTITY", IsPrimaryKey=true, CanBeNull = false)]
        public int Id { get; set; }

        [Column(DbType = "nvarchar(40)", CanBeNull = false)]
        public string Name { get; set; }

        [Column(DbType = "nvarchar(100)", CanBeNull = false)]
        public string Email { get; set; }
    }
}

然后使用来自任何其它组件在DataContext:

using (TestLinq2Sql.Shared.SharedContext shared = 
    new TestLinq2Sql.Shared.SharedContext(
        ConfigurationManager.ConnectionStrings["myConnString"].ConnectionString))
{
    var user = shared.Users.FirstOrDefault(u => u.Name == "test");
}  


Answer 4:

这看起来像一个错误 - 我们特殊情况单在主键上做本地查找,但它看起来像这样的代码路径不正确抓取的元数据。

1 = 1的黑客将意味着它会通过正常的数据库往返但真正的错误,应提交...



Answer 5:

你问几个问题在这里贾罗德,你可以更具体一点吗? 也就是说,你只是想知道为什么你的方法失败? 或者,也许你想在不同的项目中使用的数据对象的方法吗? 我假设你没有尝试使用LINQ到SQL的数据库映射层和你使用它作为一个域模型? 在这种情况下,一举两得应用程序实现同一个域(业务流程,验证等)?



文章来源: LINQ to SQL - mapping exception when using abstract base classes