假设我有这些简化的EF生成实体......
public class PurchaseOrder
{
public int POID {get;set;}
public int OrderID {get;set;}
public int VendorID {get;set;}
public IEnumerable<Order> Orders {get;set;}
}
public class Order
{
public int OrderID {get;set;}
public decimal Price {get;set;}
public IEnumerable<Item> Items {get;set;}
}
public class Item
{
public int OrderID {get; set;}
public string SKU {get;set;}
public int VendorID {get;set;}
public Order Order {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
商业逻辑:
订单可以有多个PO,一个用于订单上的每个不同供应商(供应商在物料级别确定).
我如何选择性地包括儿童实体?
查询PO时,我想自动为订单和项目添加子项目.
我完成了这个,使用Include()...
Context.PurchaseOrders.Include("Orders.Items");
Run Code Online (Sandbox Code Playgroud)
这是它的工作并拉回相关实体,但是,我只想包含其VendorID与PurchaseOrder实体的VendorID匹配的Item实体.
对于传统的SQL,我只是在JOIN条件中包含它,但EF在内部构建它们.
我可以使用什么LINQ魔术告诉EF应用条件,而无需在实体之间手动创建JOIN?
语境:
User
使用public virtual ICollection<Topic> CreatedTopics
导航属性(延迟加载);Topic
具有public virtual User Creator
导航属性;DataServiceController : DbDataController<DefaultDbContext>
,Web API beta,ASP.NET MVC 4 Beta,单页应用程序;Web API操作:
public IQueryable<Topic> GetTopics()
{
// return DbContext.Topics; // OK
return DbContext.Topics.Include("Creator"); //With Exception
}
Run Code Online (Sandbox Code Playgroud)结果:"w3wp.exe中出现未处理的microsoft .net框架异常"
这里的问题似乎是:我不应该在两个实体中添加导航属性(导致循环引用?),如果我CreatedTopics
在User
类中删除导航属性,它将再次正常.
所以,在上面列出的类似上下文中,这是我的问题:
我看过很多相关的帖子,但还不够清楚:(,
谢谢你的帮助!
院长
navigation-properties entity-framework-4 ef-code-first asp.net-web-api
我在刷新相关的实体集合时遇到了一些麻烦.
基本上问题如下:
public class Student
{
public virtual ICollection<Lecture> Lectures { get; set; }
public void AddLecture(Lecture lecture)
{
Lectures.Add(lecture);
}
public void CancelChanges()
{
_context.Refresh(RefreshMode.StoreWins, this);
_context.LoadProperty(this, (o) => o.Lectures,
MergeOption.OverwriteChanges);
}
}
public class Grade
{
public virtual Student { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在我有一些用于添加讲座的GUI,如果我们想要,我们可以取消编辑过程:
public void ExampleEdit()
{
Student student = _context.Students.SingleOrDefault(/* blah */);
student.AddLecture(_context.Lectures.SingleOrDefault(/* e.g. math */));
student.CancelChanges();
// At this point student SHOULD have no lectures anymore since the
// property was loaded with overwrite …
Run Code Online (Sandbox Code Playgroud) 这里有点沮丧.我正在尝试找到一种方法来支持实体框架的更新级联,并且似乎没有内置方式.对网络的研究基本上表明每个人都说你永远不应该改变主键值,但是有一些有效的情况你需要(例如UPC值作为主键,而UPC条形码现在变得更大,这意味着更新现有的和保持适当的外键关系).
一种方法显然是利用SavingChanges事件,查看主键字段是否正在更改,如果是,则遍历导航属性并以这种方式更新子表.
从理论上讲,这可行.但这听起来很麻烦.谁有更好的主意?不能相信比尔会因为大多数人不这样做而将这些东西排除在框架之外.SQL Server仍然支持它...
谢谢!
entity-framework cascade foreign-key-relationship navigation-properties
让我们举个例子来解释我的问题。
我的表1
+id
+myTable2Id
我的表2
+id
我的视图1
+id
+myTable2Id
MyView1 存在的情况下,来自 MyTable1 的数据。现在我想从我的 EF6.1 代码优先方法在我的视图中创建一个导航属性到 MyTable2。
我知道从数据库优先的方法中可以实现,但是从代码优先的方法中也可以实现吗?
编辑:
我在互联网上搜索了一些,但由于“视图”一词的含义很多,因此很难找到有关它的信息。
同样使用我尝试过的代码中的方法,我总是收到无法完成迁移的错误。因为迁移尝试向视图添加外键,这是不可能的。
编辑2:
详细说明我的解释。我希望能够通过以下方式在代码中处理它:
Guid table2Id = context.MyView1.FirstOrDefault().MyTable2.id;
Run Code Online (Sandbox Code Playgroud)
编辑3:
我会再详细说明一下,看看我是否能更好地解释我的问题。
当我将以下内容添加到我的视图实体时:
public virtual MyTable2 Table2 { get; set;}
Run Code Online (Sandbox Code Playgroud)
EF 会自动生成以下迁移:
public override void Up() {
CreateIndex("MyView1", "MyTable2Id");
AddForeignKey("MyView1", "MyTable2Id", "MyTable2", "id")
}
Run Code Online (Sandbox Code Playgroud)
在运行 update-database 时出现以下错误:
“无法在视图 'MyView1' 上创建索引,因为该视图未绑定架构”
编辑4:
在评论的帮助下,迁移不是石头......而且是可变的,我做到了。
我使用了以下流畅的API:
// Map one-to-zero or one relationship
modelBuilder.Entity<MyTable2>()
.HasRequired(t => t.MyTable1)
.WithOptional(t => t.MyTable2);
modelBuilder.Entity<MyTable1>()
.HasOptional(t => t.MyTable2);
Run Code Online (Sandbox Code Playgroud)
并将我的表更改为:(FK 到 MyTable2 并从视图中删除) …
c# entity-framework navigation-properties entity-framework-6 entity-framework-6.1
在项目中工作时,我看到了一个奇怪的行为,我无法理解加载导航属性。
这是一个重现这个“问题”的小例子。
我想加载一年,但不包括公司的数据(导航属性)。
我的代码:
public static Year GetYear(int id)
{
using (var context = new testModelContainer())
{
var result = context.YearSet.FirstOrDefault(c => c.Id == id);
//Company test = context.CompanySet.Where(c => c.Id == id).FirstOrDefault();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
这将返回我想要的年份,导航属性中没有数据,但是如果我取消注释该行并只执行该行,可能是因为我想知道公司名称或其他什么,它会自动将公司数据包含到公司中年度最佳导航属性。
知道如何防止这种行为吗?出于安全原因,我想避免发送“父母”的数据。
我正在使用 EF 6、.NET 4.5。
当我在EF6中使用.Include语法时,始终会加载反向导航属性.有没有办法把它关掉?这是一个示例查询.
private static IQueryable<Account> GetAccountsEager(this IRepository<Account> repository)
{
return repository
.Queryable()
.Include(e => e.AccountLocations
.Select(l => l.Address.City.State.Country));
}
Run Code Online (Sandbox Code Playgroud)
这给了我帐户的AccountLocations集合.但是,地址'城市上有这个反向导航属性:
public virtual ICollection<Address> Addresses { get; set; }
Run Code Online (Sandbox Code Playgroud)
..然后它重新加载所有反向导航地址,以便在查询中提供比我想要的更多的数据.我可以以某种方式关闭反向导航吗?
我只是从实体中删除反向导航属性,但在其他情况下,我实际上想要向后看以从城市获取地址.
谢谢.
编辑1:
我刚才注意到一些奇怪的东西.这不会加载城市的反向导航地址:
return repository.Queryable()
.Include(e => e.BillToAddress.AddressType)
.Include(e => e.BillToAddress.City.State.Country);
Run Code Online (Sandbox Code Playgroud)
但是,如果我添加这样的包含:
return repository.Queryable()
.Include(e => e.BillToAddress.AddressType)
.Include(e => e.BillToAddress.City.State.Country);
.Include(e => e.AccountLocations.Select(a => a.Address.City.State.Country));
Run Code Online (Sandbox Code Playgroud)
然后为e.BillToAddress.City和每个AccountLocation的Address.City加载反向导航地址.为什么添加.Select在第三个包括影响第二个包含?
exec sp_executesql N'SELECT
//removing [ProjectX].[Property] AS [Property] for brevity
//essentially a line for each property of the syntax above...
FROM ( SELECT
[Limit1].[AccountId] AS …
Run Code Online (Sandbox Code Playgroud) 我有三个模型课
public class Item1{
public int Id;
public List<Item2> Item2List { get; set; }
}
public class Item2{
public int Id;
//this is the FK
public int Item1Id {get;set;}
public Item1 Item1 {get;set;}
//Not in db. Ignored field in EntityTypeConfiguration
public int Item3Count;
public List<Item3> Item3List { get; set; }
}
public class Item3{
public int Id;
//this is the FK
public int Item2Id {get;set;}
public Item2 Item2 {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我想返回Item1的列表以及关联的Item2的列表,并加载与Item 2关联的Item3List的COUNT而不加载Item3List。
这是我现在正在做的事情:
public IEnumerable<Item1> GetItems()
{
return base.Query().Include(item1 => …
Run Code Online (Sandbox Code Playgroud) 场景:我想在数据库中添加一个具有导航属性的实体,该实体具有导航属性......等等.基本上,数据库中的表是相互连接的 - 所有这些表.
我使用EF4.3和上下文/请求模式,所以我不想启用Lazy加载; 它只需要花费太多时间来加载我需要的实体.到目前为止,我已经知道除了使用这样的include方法之外别无他法.
context.Set<TEntity>().include("navproperty1").include("navproperty1.navproperty1.1")... and so on.
Run Code Online (Sandbox Code Playgroud)
这样可维护性会很糟糕,而且它是很多代码,但是如果我不想手动为每个实体类型编写所有包含,还有其他方法吗?
我正在研究EF 5 Code-First解决方案,我正在尝试使用Repository模式更新现有实体并使用已修改的实体:
public void UpdateValues(T originalEntity, T modifiedEntity)
{
_uow.Context.Entry(originalEntity).CurrentValues.SetValues(modifiedEntity);
Run Code Online (Sandbox Code Playgroud)
我的简化域对象如下所示:
public class PolicyInformation : DomainObject
{
//Non-navigation properties
public string Description {get;set;}
public bool Reinsurance {get;set;}
...
//Navigation properties
LookupListItemFormType FormType {get;set;}
...
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是该CurrentValues.SetValues(modifiedEntity);
方法似乎只更新标量和复杂类型属性,但不更新导航属性.我已经看到这种情况发生在很多人身上,但仍然不知道为什么会这样.但是,我发现如果我在执行后手动设置这些导航属性,UpdateValues
一切正常:
_policyInfoRepo.UpdateValues(existingPolicyInfo, info);
existingPolicyInfo.FormType = info.FormType;
Run Code Online (Sandbox Code Playgroud)
问题是,因为我使用通用存储库:如何在域对象中获取导航属性列表?也许通过linq,反射或任何其他方式,以便我的存储库中的更新方法可以循环遍历它们并自动设置它们?
像这样的东西:
public void UpdateValues(T originalEntity, T modifiedEntity)
{
//Set non-nav props
_uow.Context.Entry(originalEntity).CurrentValues.SetValues(modifiedEntity);
//Set nav props
var navProps = GetNavigationProperties(originalEntity);
foreach(var navProp in navProps)
{
//Set originalEntity prop value to modifiedEntity value
}
Run Code Online (Sandbox Code Playgroud)
谢谢!