我想知道为什么DbContext对象上没有Detach方法,就像ObjectContext一样.我只能假设这个遗漏是故意的,但我很难弄清楚原因.我需要能够分离和重新附加实体(例如,在ASP.NET项目中放入缓存).但是,由于我无法分离实体,当我尝试附加与先前上下文关联的实体时,我得到"实体对象不能被IEntityChangeTracker的多个实例引用"异常.
这是什么指导?我错过了什么吗?
我写了一些关于实体框架的假设,然后是几个问题(所以请纠正我错在哪里).我正在尝试使用EF 4的POCO.
我的假设:
假设这是正确的,这是我的问题:
如果不将所有实体保留在同一个EF图表上,那么如何保持数据完整性,如果没有"客户","订单"就不能存在? 这仅仅是存储库的一个功能,只是为了验证完整性而加载数据,还是我们"尝试/捕获"数据库参照完整性错误?
你不会为每个实体创建一个EF图吗? 例如,我不希望客户的更改和产品的更改一起写入,因为它们彼此无关(将它们放在同一图表上会导致它们一起写入).或者EF图的范围是否包含存储在同一存储介质中的所有类似实体?
将这样的实体分开是一种规范,还是只有一个图表来保存所有实体?我会想到后者,但我的想法越来越好.
我发现的所有示例都引用了一个名为ObjectContext的类,它似乎不存在于CTP5中.我必须强调,CTP5是我第一次接触实体框架.
我有一个已连接到我的DbContext的断开连接的POCO.SaveChanges不会接受更改,我如何告诉我的上下文更新该实体?
_context.Users.Attach(user);
// The user has been replaced.
_context.SaveChanges();
// The change is not saved.
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
更新12/01/2011
对于大多数人来说可能是显而易见的,但作为EF的第一次使用者,我没有想到附加已经附加的对象会清除之前的状态.这给我带来了很多痛苦.但是我想以一种非常通用的方式使用Repository模式,这种方式不关心对象是否已经附加或者是作为ASP.NET MVC绑定的结果而新创建的.所以我需要一种UpdateUser方法,我在下面附上了它.
public User UpdateUser(User user) {
if (_context.Entry(user).State == EntityState.Detached) {
_context.Users.Attach(user);
_context.Entry(user).State = EntityState.Modified;
}
return user;
}
Run Code Online (Sandbox Code Playgroud)
该方法显然假设对象以某种方式存在于数据存储中,UpdateUser毕竟它被称为.如果对象已经附加,您将受益于对象的先前状态,这反过来将允许对数据库进行优化更新.但是,如果未附加对象,则该方法会强制整个对象变脏.
现在似乎很明显,不是之前.希望它可以帮助某人.
丰富
<RANT_MODE>
EF代码优先方法意味着节省大量时间,但暂时我只看到玩具示例,并花了几个小时试图了解如何使它生成我想要的数据库.但仍然希望尤里卡时刻:-)
<RANT_MODE />
关于问题!
我试图了解EF如何映射和检索对象关系.什么时候我应该标记一个属性virtual?(public Person Owner { get; set; }与对比一样public virtual Person Owner { get; set; }.)在代码优先的几十个例子中,我看到他们似乎可以互换地使用这些,而没有太多的解释.我所知道的是导航属性(public virtual ICollection<Person> Owners { get; set; })需要是virtual为了使延迟加载成为可能(正确...?),但这在非集合的世界中如何应用?
public int OwnerId { get; set; }除了我感兴趣的'main'属性之外,我无法找到关于是否应该包含外键字段()的任何信息public Person Owner { get; set; }.我试着不这样做,EF亲切地自动添加了一个Owner_Id在我的表中命名的int列,似乎理解了我的意图.
在Code First的约定("外键"部分)中,EF团队提到"在关系的依赖端包含外键属性是很常见的",并且"Code First现在将推断任何名为''的属性(即OwnerId)[...]与主键具有相同的数据类型,表示关系的外键".IE浏览器.如果我有两个EF将知道他们是相关的.
但除了"异物"本身之外,明确指定持有FK的此类属性是否被视为良好做法?
正如我上面提到的,即使我只public Person Owner { get; set; }在我的对象中(例如Event),该表Events将包含Owner_Id由EF自动添加的列.更重要的是,在检索时,我将可以访问属性 …
.net mapping entity-relationship entity-framework code-first
我知道EF4仍在开发中,但作为该主题的新手,我需要一个文档,教程等EF 4代码第一种方法.所有信息都在EF 4团队博客中,但分散在不同的帖子中.全面覆盖将是非常好的.
谁知道这样的地方?
我正在使用实体框架Code First CTP5,我试图找到一种方法来添加一个约定来改变外键名称的生成方式.这是一个例子:
public class Lead
{
public int Id {get; set;}
// A lot of other fields
public virtual User AssignedTo { get; set; }
}
public class User
{
public int Id {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
潜在客户可以与用户相关联.在Leads表的DB for AssignedTo中生成的字段称为UserId.
我的模型完全独立于实体框架.所以我不想使用EF的属性.我想在可能的情况下使用约定将字段命名为AssignedToUserId.
我的问题结果是有两个上下文.我重新编写了我的代码,只有一个上下文,我的问题就消失了.
我有一个User,它有一个UserContact列表,它本身有一个ContactOption.它是一个相当简单的1到多个,多对1,中间有UserContact表.
如果我将用户拉出数据库并创建一个新的UserContact,但将ContactOption设置为现有项目(我从数据库中取出),当我保存更改时,实体框架在数据库中创建一个新的ContactOption,基本上是我添加到UserContact的副本(除了它获得一个新的id).
我已经与它斗争了好几个小时,无法解决这个问题.有任何想法吗?
我正在使用Repository模式进行数据库查询,但我确保它们共享相同的上下文.
我用这个将用户拉出数据库:
var user = _context.Users.Include("UserContacts.ContactOption")
.Where(id => id == 1);
Run Code Online (Sandbox Code Playgroud)
并提供以下联系方式:
var co = _context.ContactOptions.FirstOrDefault(c => c.Id == id);
Run Code Online (Sandbox Code Playgroud)
我将ContactOption添加到UserContact,如下所示:
var contactOption = _context.ContactOptions.FirstOrDefault(c => c.Id == someId);
var contact = new UserContact { ContactOption = contactOption };
contact.Data = "someData";
user.UserContacts.Add(contact);
Run Code Online (Sandbox Code Playgroud)
我的模型看起来像这样:
public class User
{
[Key]
public int Id { get; set; }
public virtual ICollection<UserContact> UserContacts { get; set; }
}
public class UserContact
{
[Key]
public int Id { get; set; …Run Code Online (Sandbox Code Playgroud) 在Fluent NHibernate中,您可以为映射设置级联设置,例如
public class StoreMap : ClassMap<Store>
{
public StoreMap()
{
Id(x => x.Id);
Map(x => x.Name);
HasMany(x => x.Staff)
.Inverse()
.Cascade.None();
HasManyToMany(x => x.Products)
.Cascade.All()
.Table("StoreProduct");
}
}
Run Code Online (Sandbox Code Playgroud)
如何在实体框架"Code First"中完成这项工作?
.net entity-framework code-first entity-framework-4 entity-framework-ctp5
使用EF CTP5,我试图做一些实体拆分,其中实体是从两个单独的表构造的.如果两个表上的键不是主键,是否可以进行拆分?
例如,Id是我在Note实体上的主键.我想从单独的表中获取我的CreatedUser详细信息,但第二个表上的主键对应于Note实体中的CreatedUserId.
modelBuilder.Entity<Note>()
.Map(mc =>
{
mc.Properties(n => new
{
n.Id,
n.Title,
n.Detail,
n.CreatedUserId,
n.CreatedDateTime,
n.UpdatedUserId,
n.UpdatedDateTime,
n.Deleted,
n.SourceSystemId,
n.SourceSubSystemId
});
mc.ToTable("Notes");
})
.Map(mc =>
{
mc.Properties(n => new
{
n.CreatedUserId,
n.CreatedUser
});
mc.ToTable("vwUsers");
});
Run Code Online (Sandbox Code Playgroud)
我看过注释只有在两个表中都存在实体主键时才能实现实体拆分?
提前致谢.