所以,假设我有一个POCO,我希望EF Code First能够持久存储到数据存储:
public class Campaign
{
public string Name { get; set; }
public double GoalAmount { get; set; }
private double AmountRaised { get; set; }
public bool GoalMet
{
get
{
return AmountRaised >= GoalAmount;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,无论出于何种原因,我不希望在AmountRaised对象外部访问该属性,但我确实希望它持久保存到数据存储中.EF Code First可以实现这一点吗?
我刚开始使用EF Code First来实现一个简单的博客.
我有一个Post对象,它有一个产品变量
virtual Product Product { get; set; }
Run Code Online (Sandbox Code Playgroud)
Product类有一组类别
virtual ICollection<Category> Categories { get; set; }
Run Code Online (Sandbox Code Playgroud)
最后该类别有一个集合帖子.
virtual ICollection<Post> Posts { get; set; }
Run Code Online (Sandbox Code Playgroud)
到目前为止,这一点运作良好.现在我想获得特定类别的帖子.我最初通过传递类别Id来在我的PostRepository中执行此操作:例如
public IQueryable<Post> GetPosts(int catId) {
var q = _db.Posts.Select(p => p).Distinct();
if (catId > 0)
q = q.Where(p => p.Product.Categories.Any(c => c.ID == catId));
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但我也使用CategoryRepository来获取我的类别.由于该类别有一个产品列表,而这些产品又有一个帖子列表,我认为最好只使用它,并从我的PostRepository中删除该类别.
但是,我遇到了一个问题.要获得帖子,我在我的控制器中使用它:
model.Category = _cr.GetCategory(catId);
model.Posts =
new PaginatedList<Post>(model.Category.Products.Select(p => p.Posts)
.AsQueryable(), pageNumber, _defaultPageSize);
Run Code Online (Sandbox Code Playgroud)
PaginatedList是NerdDinner接收IQueryable的那个.现在,这个错误,因为我传递了一个
IQueryable<ICollection<Post>>
Run Code Online (Sandbox Code Playgroud)
所以我的问题是如何从我的Category实体中获得IQueryable?我确定答案很简单,但我一直在尝试各种组合无济于事.
我正在用一个实体创建一个非常简单的EF4代码第一个项目.
public class Activity
{
public Guid Id { get; set; }
public string Description { get; set; }
public List<DateTime> DateDone { get; set; }
<snip>
public Activity()
{
if(DateDone==null)
DateDone = new List<DateTime>();
}
}
Run Code Online (Sandbox Code Playgroud)
我重建我的项目,然后运行MVC3应用程序并生成数据库(确认,我已添加和删除列),我的数据是种子(当我修改种子数据时它在屏幕上更改)
我能够:
var activity = db.Activities.Find(id);
activity.DateDone = DateTime.Now;
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
但是数据没有保存.我检查了数据库,因为只有一个表(Activity),它有所有相应的字段.我希望它应该有第二个表,ActivityDateDone有两个字段,ActivityGuid和DateDone.
我在做这项工作时缺少什么?
我正在将我的项目从数据库优先迁移到代码优先.
实体框架做了一些很好的工作来创建我的新数据库(应该模仿旧的数据库).
我正在使用数据注释和流畅的API组合来描述我的表.
我的数据库有一些索引,我也希望实体框架能够创建它们.看来,执行此操作的旧方法是定义自己的初始化程序并使用自定义T-SQL.
但是现在我们有了EF迁移,它应该更容易实现.
我似乎无法弄清楚如何将CreateDatabaseIfNotExists <>与自动迁移相结合来创建索引.我尝试使用MigrateDatabaseToLatestVersion <,>但在创建数据库后似乎没有执行迁移.
现在我们有Entity Framework 4.3,在数据库创建上创建索引和约束的正确方法是什么?
最终答案:
我在InRequestScope()方法中使用了@WiktorZychla answer和Ninject的组合.我重新考虑我的存储库以接受上下文注入,然后在我的NinjectControllerFactory中添加了以下行:
ninjectKernel.Bind<EFDbContext>().ToSelf().InRequestScope();
Run Code Online (Sandbox Code Playgroud)
(注意:我更换了:
ninjectKernel.Bind<ISellingLocation>().To<EFSellingLocationRepository>().InReque??stScope().WithConstructorArgument("context",new EFDbContext());
Run Code Online (Sandbox Code Playgroud)
我在其中一条评论中提到的一行,其中:
ninjectKernel.Bind<ISellingLocation>().To<EFSellingLocationRepository>();
Run Code Online (Sandbox Code Playgroud)
因为它导致错误)
我还用nuget安装了Ninject.MVC3,它创建了文件:"NinjectWebCommon.cs",其中包含以下行:
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
Run Code Online (Sandbox Code Playgroud)
虽然有人说这一行是可选的,但其他文章声明应该使用它来使InRequestScope在MVC站点中正常工作.
原始问题:
我目前有很少的EF存储库,每个看起来类似于以下内容:
public class EFCityRepository : ICityRepository
{
private EFDbContext context = new EFDbContext();
public bool Create(City cityToCreate)
{
...
}
public City Get(int cityID)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,现在我正在使用单个全局EFDbContext进行所有操作,从我读到的这个很糟糕 - 所以我尝试将它(在Create,Get和其他方法中)更改为"using"语句,类似于下列:
public City Get(int cityID)
{
using(EFDbContext context)
{
...some opeartions…
return entities;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我遇到了很多与实体延迟加载相关的问题,我必须使用类似下面的内容:
context.Entry(getResult.FirstOrDefault()).Reference(x => x.Address).Load();
context.Entry(getResult.FirstOrDefault()).Reference(x => x.Agency).Load();
context.Entry(getResult.FirstOrDefault().Address).Reference(x => x.City).Load();
Run Code Online (Sandbox Code Playgroud)
只是为了简化以我想要的方式工作,否则每次我尝试访问地址时,我得到:"ObjectContext实例已被处理,不能再用于需要连接的操作".当然,当上下文是全局的时,它可以正常工作.
我需要一些建议:我应该使用本地上下文并使用急切加载而不是延迟加载?或者这里的全球背景是否可以接受?
还有人认为如何使用延迟加载?正如我所看到的 - 我必须为使用某个存储库的每个操作编写单独的逻辑 - 或者我错了? …
我正在尝试在VS Express中创建MVC 4应用程序(OdeToFood教程).我在模型中创建了这个类.
但是当我运行代码时,没有创建数据库"OdeToFoodDB2"
namespace OdeToFood.Models
{
public class OdeToFoodDB2 : DbContext
{
public DbSet<Resturant> Resturant { get; set; }
public DbSet<ResturantReview> ResturantReview { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
在web.config文件中,我有以下连接字符串
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-OdeToFood-20140306003945;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-OdeToFood-20140306003945.mdf" providerName="System.Data.SqlClient" />
Run Code Online (Sandbox Code Playgroud)
但是这个db不包含我在Model文件夹中指定的表.
<connectionString>
<add name="SchoolContext"
connectionString="Data Source=(local); database=Sample; integrated security=true;"
providerName="System.Data.SqlClient"
/>
Run Code Online (Sandbox Code Playgroud)
上面是我的连接字符串.但是当我运行应用程序时,它会给出一个错误名称
无法读取配置节'connectionString',因为它缺少节声明
我该如何解决?
我的代码有什么问题,我得到以下错误:
无法确定相关操作的有效排序.由于外键约束,模型要求或存储生成的值,可能存在依赖关系
码:
食品类:
public class Food
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public short Id { get; set; }
//some Property
public string Name { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
班级人员:
public class Person
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
//some Property
public string FirstName { get; set; }
[ForeignKey("BestFoodId")]
public Food BestFood { get; set; }
public short BestFoodId { get; set; }
public virtual ICollection<Food> FavoriteFoods { get; set; …Run Code Online (Sandbox Code Playgroud) c# entity-framework foreign-keys code-first entity-framework-6
使用实体框架4.我以前创建了一个Code First数据库,一段代码需要删除并添加16个对象,每个需要6秒.每个查询的时间超过300毫秒!
删除/添加发生在foreach范围内,并且在SaveChanges()外部foreach.

在上面的图像中,您可以看到,对于16个呼叫,每个都需要6秒,这是34%的时间.
这对我来说听起来不正常...... 为什么会这样,我怎样才能提高性能呢?
如果没有解决方案:我可以使用任何变通方法吗?重写我的项目会很痛苦......
这是Employee我在MVC项目中使用的模型类.
public class Employee
{
[Required]
public string Name { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int EmployeeID { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public int SkillID { get; set; }
[Display(Name="Employee Skill")]
public Skill EmployeeSkill { get; set; }
public virtual List<Skill> EmployeeSkills { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我已将[DatabaseGenerated(DatabaseGeneratedOption.Identity)]属性添加到EmployeeID属性中.但是,当我尝试插入时没有指定EmployeeID,作为输入值,我得到以下错误...
无法将值NULL插入列'EmployeeID',表'MVCTheRightWayContext-20141028005000.dbo.Employees'; 列不允许空值.INSERT失败.该语句已终止.
code-first ×10
c# ×5
asp.net-mvc ×3
asp.net ×2
.net ×1
foreign-keys ×1
indexing ×1
lazy-loading ×1
performance ×1
sql-server ×1