LINQ到SQL 1:1插入

LINQ到SQL 1:1插入,linq,linq-to-sql,database-design,foreign-keys,Linq,Linq To Sql,Database Design,Foreign Keys,我目前正面临这个问题。我已经通过LINQ到SQL将POCO手动映射到我的数据库表。我希望将所有这些对象/表放在一个上下文(视为事务)下,以便在事务中失败时,所有对象/表都将回滚 现在我面临的问题是我有UserLogin和UserProfile(1:0-1关系)。它们的结构是,UserLogin的id是UserProfile的PK和FK,UserProfile也是如此。在UserLogin上,它设置为自动生成一个标识,IsDBGenerated设置为true。另一方面,UserProfile没有生

我目前正面临这个问题。我已经通过LINQ到SQL将POCO手动映射到我的数据库表。我希望将所有这些对象/表放在一个上下文(视为事务)下,以便在事务中失败时,所有对象/表都将回滚

现在我面临的问题是我有UserLogin和UserProfile(1:0-1关系)。它们的结构是,UserLogin的id是UserProfile的PK和FK,UserProfile也是如此。在UserLogin上,它设置为自动生成一个标识,IsDBGenerated设置为true。另一方面,UserProfile没有生成ISDBG

UserProfile在UserLogin中设置为EntityRef,由于它们来自同一上下文,因此在创建时我将UserLogin.UserProfile=new UserProfile()

分配完所有属性后,我完成了table.InsertOnSubmit(UserLogin)和context.SaveChanges()

这才是真正的问题所在。UserProfile的id保持为0

有人能帮忙吗


对不起,我没说清楚。正在使用的SQL Server是MS SQL Server 2008

实体结构是这样的,

UserLogin在注册时是强制的,而UserProfile不是,这使它成为1:0-1关系。因此,在两个表上都使用自动增量是不明智的

UserProfile的PK也是一个引用UserLogin的FK

@GertArnold,是的,我确实在asp.net代码后面设置了UserProfile id=UserLogin id,但在保存上下文之前,UserLogin的id将保持为0,因为此时,我希望将两个记录添加到一起,并且想知道Linq to Sql是否有某种方法来解决此问题。既然我已经添加了关联属性,那么linqtosql应该能够识别这种依赖关系,并在提交时添加id,或者至少,这是我的一厢情愿

在我的UserProfile中,我有以下代码片段:

[Column(IsPrimaryKey = true)]
public long id { get; set; }
private EntityRef<UserLogin> _login;
[Association(ThisKey = "id", Storage = "_login")]
public UserLogin UserLogin { get { return _login.Entity; } 
    set { _login.Entity = value; } }
此时,两个ID都为零,因为它们都尚未插入


当我执行context.SubmitChanges()时,UserLogin的id将获得递增值,但UserProfile的id将保持为0。我之所以想将两者包装在同一个上下文中并一起提交,是为了避免出现类似“提交了UserLogin”这样的情况,但UserProfile会出错。因此,在我的数据库中,有一个登录记录,但没有配置文件,弄乱了我的数据。

为了理解你的意思,我不得不多次阅读这个问题。这条线

它们的结构是,UserLogin的id是UserProfile的PK和FK,UserProfile也是如此

最初似乎意味着
UserLogin
有一个外键指向
UserProfile
,而
UserProfile
有一个外键指向
UserLogin
。但我现在认为,您要做的是在两个表中对PK使用相同的值;如果我有
UserLoginId
=123,然后我去创建一个配置文件,那么您希望我有
UserProfileId
123

你为什么这么做?从数据库的角度来看,这没什么问题(尽管我认为这不是特别有益,也有点令人困惑),但LINQ to SQL需要一个主键,它知道主键是单行的主键,而不是用作任何其他表的主键。它需要一个外键,而不是主键

UserProfile
表中的值123实际上是
UserLogin
的外键,但不是主键。它不需要是主键,这样做会使LINQ对SQL的理解更加混乱。让
UserProfile
拥有自己的PK。创建一个自动递增的标识,并将外键更改回
UserLogin
。你所有的问题都会解决的

UserLogin
PK - UserLoginId int identity

UserProfile
PK - UserProfileId int identity
FK - UserLoginId int 

根据我的经验,LINQ-to-SQL和实体框架在使用简单的代理主键时效果最好,与其他任何东西无关。任何过于棘手或非标准的问题都会比任何明显的好处或简单性更让您头疼。

您使用的是哪种类型的数据库?既然UserProfile是UserLogin的子记录(至少在我看来是这样),为什么不能只使用UserProfile.Id作为SqlServer中的一个自动递增字段,如果它是Oracle…,请添加一个序列?是的,你做对了。这正是我想要做的,让UserProfile的id=UserLogin的id,跳过代理键。在EF中,我可以通过使用fluent api实现这一点,但在L2S中则不行。遗憾的是,这个项目仍然停留在L2S上,如果我决定将其转换为EF4.1,这将给我带来困难。无论如何,我将向我的DBA建议您的方法,看看我们如何从那里开始。谢谢。我也遇到了同样的问题(下面的链接),如果我不得不这样做,那么我将失去关系数据库中硬编码的一对一关系。这意味着有可能打破这一重要限制@andicrook您的问题已被删除,因此我无法发表评论。但我并不完全同意——您仍然可以在外键列上添加一个唯一的约束,以确保1:1。
UserLogin login = new UserLogin();
// All assigning here
login.UserProfile = new UserProfile();
// Assign here
login.userProfile.id = login.id;
UserLogin
PK - UserLoginId int identity

UserProfile
PK - UserProfileId int identity
FK - UserLoginId int