代码之家  ›  专栏  ›  技术社区  ›  bevacqua

LINQ中公共列的抽象基类

  •  8
  • bevacqua  · 技术社区  · 15 年前

    这就是我目前所拥有的

    using System;
    using System.Collections.Generic;
    using System.Data.Linq;
    using System.Data.Linq.Mapping;
    using System.Linq;
    using System.Text;
    
    namespace Firelight.Business
    {
        public interface IBaseEntity<K>
        {
            K Id { get; }
        }
    
        /// <summary>
        /// Base business database connection object, primary key is int
        /// </summary>
        /// <typeparam name="T">Table name</typeparam>
        public abstract class BaseEntity<T> : BaseEntity<T, Guid> where T : class, IBaseEntity<Guid>
        {
        }
    
        /// <summary>
        /// Base business database connection object
        /// </summary>
        /// <typeparam name="T">Table name</typeparam>
        /// <typeparam name="K">Primary key type</typeparam>
        public abstract class BaseEntity<T,K> : IBaseEntity<K> where T : class, IBaseEntity<K>
        {
            // Avoids having to declare IBaseConnection at partial class level
            [Column(Name = "Id", CanBeNull = false, IsPrimaryKey = true, IsDbGenerated = true)]
            public K Id { get; set; } // { return default(K); }
    
            public static Table<T> Table 
            {
                get { return LinqUtil.Context.GetTable<T>(); } 
            }
    
            public static T SearchById(K id)
            {
                return Table.Single<T>(t => t.Id.Equals(id));
            }
    
            public static void DeleteById(K id)
            {
                Table.DeleteOnSubmit(SearchById(id));
                LinqUtil.Context.SubmitChanges();
            }
        }
    }
    

    我的问题是映射不起作用:

    数据成员'系统.Guid[或系统.Int32]类型的Id' “X” 不是类型映射的一部分 继承层次的根?

    找不到密钥的密钥成员“Id” 或者“X”上的字段或属性

    我试着把K改成Guid,结果成功了,但为什么?我看不出通用类型在这里有什么问题

    所以,问题是:我怎样才能让这样的课程成功?我需要它,这样我就可以访问一个通常命名的PK(Id),它总是有类型K[它是Guid或Int32],并重构基本函数,比如select和delete by Id

    编辑:

    using System;
    using System.Collections.Generic;
    using System.Data.Linq;
    using System.Linq;
    
    namespace Firelight.Business
    {
        public interface IBaseEntity<K>
        {
            K Id { get; set; }
        }
    
        /// <summary>
        /// Base business database connection object
        /// </summary>
        /// <typeparam name="T">Table name</typeparam>
        public abstract class BaseEntity<T> : IBaseEntity<Guid> where T : class, IBaseEntity<Guid>
        {
            // Avoids having to declare IBaseConnection at partial class level
            public Guid Id { get; set; }
    
            public static Table<T> Table 
            {
                get { return LinqUtil.Context.GetTable<T>(); } 
            }
    
            public static T SearchById(Guid id)
            {
                return Table.Single<T>(t => t.Id.Equals(id));
            }
    
            public static void DeleteById(Guid id)
            {
                Table.DeleteOnSubmit(SearchById(id));
                LinqUtil.Context.SubmitChanges();
            }
        }
    }
    

    我想要的基本上是相同的,用K替换Guid并使类成为BaseEntity(这样我就可以对Int32和Guid PKs使用相同的类

    1 回复  |  直到 15 年前
        1
  •  9
  •   StaceyGirl    8 年前

    您所要做的将不适用于LINQ to SQL。要使用LINQ To SQL的继承,必须在基类上使用[InheritanceMapping]属性。假设有一个基类叫做Vehicle,还有一个子类叫做Motorcycle:

    [InheritanceMapping(Type = typeof(Motorcycle), IsDefault = true, Code = 1)]
    [Table]
    public class Vehicle
    {
        [Column]
        public string Make { get; set; }
    
        [Column]
        public string Model { get; set; }
    
        [Column(IsDiscriminator = true, Name="VehicleTypeId")]
        public VehicleType VehicleType { get; set; }
    }
    
    public class Motorcycle : Vehicle
    {
        // implementation here
    }
    

    为了使这种继承在LINQ to SQL中工作,必须应用 [InheritanceMapping] 对基阶级 您还必须有一个鉴别器列(例如,上面示例中的VehicleType)。注意,InheritanceMapping中的代码是“1”-这意味着如果数据库中的车辆类型是“1”,那么它将创建Motorcycle子类。你申请一个 [继承映射] 每个 你支持的子类。

    知道

    更新 这是有效的:

    public abstract class BaseEntity<T, K> : IBaseEntity<K> where T : class, IBaseEntity<K>
    {
        public abstract K Id { get; set; }
    
        public static Table<T> Table
        {
            get { return context.GetTable<T>(); }
        }
    
        public static T SearchById(K id)
        {
            return Table.Single<T>(t => t.Id.Equals(id));
        }
    
        public static void DeleteById(K id)
        {
            Table.DeleteOnSubmit(SearchById(id));
            context.SubmitChanges();
        }
    }
    

    注意区别是我没有 [Column] Id属性的属性。也注意到我把它抽象化了。实现类如下所示:

    [Table(Name = "dbo.Contacts")]
    public class Contact : BaseEntity<Contact, int>
    {
        [Column]
        public override int Id { get; set; }
        [Column]
        public string FirstName { get; set; }
        [Column]
        public string LastName { get; set; }
    }
    

    Id 有一个 [栏]

    BaseEntity 具有Id属性和子类(在我的示例中 Contact