none
建立dbml文件让VS自动生成实体类时的没有正确生成父子关系的问题 RRS feed

  • 问题

  • 在比较复杂的一对多的关系中,vs无法为父子双方生成关于对方的引用。

    我的实际情况如下:

    (图片地址是http://i52.tinypic.com/2eygzv5.png)

    外键用红圈圈出

    生成的实体类代码的属性字段如下:
    Member类
    
    private System.Guid _ID;
    
    private string _Account;
    
    private string _Password;
    
    private string _Nickname;
    
    private string _LastestIp;
    
    private bool _IsOnline;
    
    private EntitySet<FriendList> _FriendList; //这里有Detail的集合哦!
    
    FriendList类
    private System.Guid _ID;
    
    private string _ListName;
    
    private System.Guid _MemberID;
    
    private int _SortNO;
    
    private bool _IsSystem;
    
    private EntityRef<Member> _Member; //它和Member的外键关系是正常的
    
    
    Friendship类
    
    private System.Guid _ID;
    
    private System.Guid _FriendID; //这个应该是关联到Member的外键,被忽视了!
    
    private System.Guid _FriendListID; //这个应该是关联到FriendList的外键,被忽视了!
    
    private System.DateTime _CreateDate;
    

    使用XML方式查看dbml文件,关联关系是正确的,但实体类中就是没有生成对应的字段

    <Table Name="dbo.FriendList" Member="FriendList">
      <Type Name="FriendList">
       <Column Name="ID" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
       <Column Name="ListName" Type="System.String" DbType="NVarChar(10) NOT NULL" CanBeNull="false" />
       <Column Name="MemberID" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
       <Column Name="SortNO" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
       <Column Name="IsSystem" Type="System.Boolean" DbType="Bit NOT NULL" CanBeNull="false" />
       <Association Name="FriendList_Friendship" Member="Friendship" ThisKey="ID" OtherKey="FriendListID" Type="Friendship" />
       <Association Name="Member_FriendList" Member="Member" ThisKey="MemberID" OtherKey="ID" Type="Member" IsForeignKey="true" />
      </Type>
     </Table>
     <Table Name="dbo.Member" Member="Member">
      <Type Name="Member">
       <Column Name="ID" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
       <Column Name="Account" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
       <Column Name="Password" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
       <Column Name="Nickname" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
       <Column Name="LastestIp" Type="System.String" DbType="NVarChar(15)" CanBeNull="true" />
       <Column Name="IsOnline" Type="System.Boolean" DbType="Bit NOT NULL" CanBeNull="false" />
       <Association Name="Member_FriendList" Member="FriendList" ThisKey="ID" OtherKey="MemberID" Type="FriendList" />
       <Association Name="Member_Friendship" Member="Friendship" ThisKey="ID" OtherKey="FriendID" Type="Friendship" />
      </Type>
     </Table>
     <Table Name="dbo.Friendship" Member="Friendship">
      <Type Name="Friendship">
       <Column Name="ID" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
       <Column Name="FriendID" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
       <Column Name="FriendListID" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
       <Column Name="CreateDate" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
       <Association Name="FriendList_Friendship" Member="FriendList" ThisKey="FriendListID" OtherKey="ID" Type="FriendList" IsForeignKey="true" />
       <Association Name="Member_Friendship" Member="Member" ThisKey="FriendID" OtherKey="ID" Type="Member" IsForeignKey="true" />
      </Type>
     </Table>
    
    我用的是VS2010

    2011年5月23日 6:46

答案

  • 你好,又仔细研究了下你的表之间的关系,我决定用Entity Framework试一下,看看Entity Framework能不能正常生成这种关系。

    下面是我生成的类中表之间关系的部分代码:

     public partial class FriendList : EntityObject

       

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_FriendList", "Friendship")]

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_FriendList_Member", "Member")]

     

    public partial class Member : EntityObject

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_FriendList_Member", "FriendList")]

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_Member", "Friendship")]

    public partial class Friendship : EntityObject

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_FriendList", "FriendList")]

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_Member", "Member")]

    可以看到EF可以清楚地生成他们之间的关系,这就使我不得不怀疑可能真的就是LINQ to SQL的问题了。我这边确实可以重现你的问题,然而又找不到合适的解决方法,所以,我还是建议你用EF。这样省心省力。

     

    谢谢,

     


    Jackie Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手



    • 已标记为答案 Behindmoon 2011年5月26日 9:40
    2011年5月26日 5:01
    版主

全部回复

  • 你好,

    可以将你的创建数据库代码贴出来吗,以便我可以重现一下你的问题。

    另外,对于你的情况,我推荐你用Entity Framework,因为微软现在主推的ORM工具就是Entity Framework, 对于LINQ to SQL不会在推出新的东西,而且Entity Framework的功能也比较强大,所以推荐你用EF试一下。 

    这儿有EF的QuickStart:http://msdn.microsoft.com/en-us/library/bb399182.aspx

    希望对你有帮助。

    谢谢,


    Jackie Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手

    2011年5月24日 8:08
    版主
  • 你好,感谢你的回复,Entity Framework还未系统的了解过,暂时不去考虑,除非遇到linq to sql无法解决的问题。=_=

    sql如下

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Member]') AND type in (N'U'))
    BEGIN
    CREATE TABLE [dbo].[Member](
    	[ID] [uniqueidentifier] NOT NULL,
    	[Account] [nvarchar](50) NOT NULL,
    	[Password] [nvarchar](50) NOT NULL,
    	[Nickname] [nvarchar](50) NOT NULL,
    	[LastestIp] [nvarchar](15) NULL,
    	[IsOnline] [bit] NOT NULL,
     CONSTRAINT [PK_Member] PRIMARY KEY CLUSTERED 
    (
    	[ID] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    END
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Friendship]') AND type in (N'U'))
    BEGIN
    CREATE TABLE [dbo].[Friendship](
    	[ID] [uniqueidentifier] NOT NULL,
    	[FriendID] [uniqueidentifier] NOT NULL,
    	[FriendListID] [uniqueidentifier] NOT NULL,
    	[CreateDate] [datetime] NOT NULL
    ) ON [PRIMARY]
    END
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FriendList]') AND type in (N'U'))
    BEGIN
    CREATE TABLE [dbo].[FriendList](
    	[ID] [uniqueidentifier] NOT NULL,
    	[ListName] [nvarchar](10) NOT NULL,
    	[MemberID] [uniqueidentifier] NOT NULL,
    	[SortNO] [int] NOT NULL,
    	[IsSystem] [bit] NOT NULL,
     CONSTRAINT [PK_FriendList] PRIMARY KEY CLUSTERED 
    (
    	[ID] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    END
    GO
    IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Friendship_FriendList]') AND parent_object_id = OBJECT_ID(N'[dbo].[Friendship]'))
    ALTER TABLE [dbo].[Friendship] WITH CHECK ADD CONSTRAINT [FK_Friendship_FriendList] FOREIGN KEY([FriendListID])
    REFERENCES [dbo].[FriendList] ([ID])
    GO
    IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Friendship_Member]') AND parent_object_id = OBJECT_ID(N'[dbo].[Friendship]'))
    ALTER TABLE [dbo].[Friendship] WITH CHECK ADD CONSTRAINT [FK_Friendship_Member] FOREIGN KEY([FriendID])
    REFERENCES [dbo].[Member] ([ID])
    GO
    IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_FriendList_Member]') AND parent_object_id = OBJECT_ID(N'[dbo].[FriendList]'))
    ALTER TABLE [dbo].[FriendList] WITH CHECK ADD CONSTRAINT [FK_FriendList_Member] FOREIGN KEY([MemberID])
    REFERENCES [dbo].[Member] ([ID])
    
    
    2011年5月24日 13:06
  • 你好,谢谢你的回复。

    我重现了一下, 发现在生成的类中并没有忽视他们的关系,下面是我这边生成的FriendShip类:

    [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Friendship")]

                public partial class Friendship

                {

                           

                            private System.Guid _ID;

                           

                            private System.Guid _FriendID;

                           

                            private System.Guid _FriendListID;

                           

                            private System.DateTime _CreateDate;

                           

                            public Friendship()

                            {

                            }

                           

                            [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ID", DbType="UniqueIdentifier NOT NULL")]

                            public System.Guid ID

                            {

                                        get

                                        {

                                                    return this._ID;

                                        }

                                        set

                                        {

                                                    if ((this._ID != value))

                                                    {

                                                                this._ID = value;

                                                    }

                                        }

                            }

                           

                            [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FriendID", DbType="UniqueIdentifier NOT NULL")]

                            public System.Guid FriendID

                            {

                                        get

                                        {

                                                    return this._FriendID;

                                        }

                                        set

                                        {

                                                    if ((this._FriendID != value))

                                                    {

                                                                this._FriendID = value;

                                                    }

                                        }

                            }

                           

                            [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FriendListID", DbType="UniqueIdentifier NOT NULL")]

                            public System.Guid FriendListID

                            {

                                        get

                                        {

                                                    return this._FriendListID;

                                        }

                                        set

                                        {

                                                    if ((this._FriendListID != value))

                                                    {

                                                                this._FriendListID = value;

                                                    }

                                        }

                            }

                           

                            [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CreateDate", DbType="DateTime NOT NULL")]

                            public System.DateTime CreateDate

                            {

                                        get

                                        {

                                                    return this._CreateDate;

                                        }

                                        set

                                        {

                                                    if ((this._CreateDate != value))

                                                    {

                                                                this._CreateDate = value;

                                                    }

                                        }

                            }

                }

    在将FriendShip 表中的ID改成主键后,我就尝试着去insert 一些数据到三个表里,请看下面我测试的代码;

                    //var insert = new FriendList

                    //{

                    //    ListName = "sdsds",

                    //    Member = new Member

                    //    {

                    //        Nickname ="dfdf",

                    //        Account ="dsdsd",

                    //        IsOnline=true,

                    //        LastestIp="dfdffdf",

                    //        Password="rerere"

                    //    },

                    //    IsSystem = false,

                    //    SortNO = 1

                    //};

     

                    //var insert = new Member

                    //{

                    //    ID = Guid.NewGuid(),

                    //    Account = "wewe",

                    //    Password = "wqwq",

                    //    LastestIp = "rerere",

                    //    IsOnline = true,

                    //    Nickname = "sdsd",

                       

                    //};

                    DateTime DateFields = new DateTime(2011, 1, 1, 0, 0, 0);

     

     

                    var insert = new Friendship

                    {

                        ID = Guid.NewGuid(),

                        CreateDate = DateFields,

                        FriendID = ctx.Members.First().ID,

                        FriendListID = ctx.FriendLists.First().ID

                    };

                    ctx.Friendships.InsertOnSubmit(insert);

                    ctx.SubmitChanges();

     

    上面代码运行良好,没有什么异常,你是不是在开发的过程中遇到什么异常或者错误呢? 如果有的话,请告诉我在什么情况下会出现异常或错误。

    谢谢,


    Jackie Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手

    2011年5月25日 5:53
    版主
  • 你好,你生成的Friendship类中没有对Member对象的引用吧,而且在Member类中也应该生成对Friendship类的集合的引用,如我所给出的代码中就有对FriendList集合的引用:

    private EntitySet<FriendList> _FriendList;

    同样,FriendList类应该也有对Friendship类的集合的引用,而Friendship类中也应当保留对FriendList类的引用。这种一对多的父子关系却没有在生成的类中体现出来。

    2011年5月25日 8:14
  • 你好,我想我知道是什么原因了,其实你的Member和FriendShip的一对多的关系是没有必要的。 完全可以删掉,并且我们还可以通过FriendList来体现出Member和FriendShip是一对多的关系。因此我试着将这个关系删除,下面就是我重新编译好的代码:

     [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.FriendList")]
     public partial class FriendList : INotifyPropertyChanging, INotifyPropertyChanged
     {
      
      private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
      
      private System.Guid _ID;
      
      private string _ListName;
      
      private System.Guid _MemberID;
      
      private int _SortNO;
      
      private bool _IsSystem;
      
      private EntitySet<Friendship> _Friendships;
      
      private EntityRef<Member> _Member;

    下面是FriendShip的代码:

     [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Friendship")]
     public partial class Friendship : INotifyPropertyChanging, INotifyPropertyChanged
     {
      
      private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
      
      private System.Guid _ID;
      
      private System.Guid _FriendID;
      
      private System.Guid _FriendListID;
      
      private System.DateTime _CreateDate;
      
      private EntityRef<FriendList> _FriendList;

    这样,FriendList类有对Friendship类的集合的引用,而Friendship类中也有对FriendList类的引用。这种一对多的父子关系就在生成的类中体现出来了。我想最终原因可能就是VS不认识你所表示的他们之间的关系。

    谢谢,


    Jackie Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手

    2011年5月25日 8:33
    版主
  • 你好,

    其实这是一个自己与自己构成父子关系的问题(会员Member的好友也是Member),按照道理来说是应该有这个关联的。如果没有这个关联的话,我想要查询一个用户所有的分组好友列表(FriendList是分组名,如我的好友、黑名单),并序列化发送给客户端。

    这样的话,想要直接使用生成的实体类貌似就很难做了。

    2011年5月25日 13:01
  • 你好,又仔细研究了下你的表之间的关系,我决定用Entity Framework试一下,看看Entity Framework能不能正常生成这种关系。

    下面是我生成的类中表之间关系的部分代码:

     public partial class FriendList : EntityObject

       

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_FriendList", "Friendship")]

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_FriendList_Member", "Member")]

     

    public partial class Member : EntityObject

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_FriendList_Member", "FriendList")]

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_Member", "Friendship")]

    public partial class Friendship : EntityObject

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_FriendList", "FriendList")]

     

           [EdmRelationshipNavigationPropertyAttribute("CarModel", "FK_Friendship_Member", "Member")]

    可以看到EF可以清楚地生成他们之间的关系,这就使我不得不怀疑可能真的就是LINQ to SQL的问题了。我这边确实可以重现你的问题,然而又找不到合适的解决方法,所以,我还是建议你用EF。这样省心省力。

     

    谢谢,

     


    Jackie Sun [MSFT]
    如果您对我们的论坛在线支持服务有任何的意见或建议,请通过邮件告诉我们。
    MSDN 论坛好帮手 立刻免费下载  MSDN 论坛好帮手



    • 已标记为答案 Behindmoon 2011年5月26日 9:40
    2011年5月26日 5:01
    版主
  • 谢谢你的帮助,我会考虑使用EF的。
    2011年5月26日 9:39