环境:
我在Webapi工作。下面是2个实体类;
public class Class1
{
public Class1()
{
this.items = new HashSet<Class2>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Class2> items { get; set; }
}
public class Class2
{
public int Id { get; set; }
public string Name { get; set; }
public int Class1Id { get; set; }
public virtual Class1 class1 { get; set; }
}
业务层: buniess层具有以下代码;
public class Class1Logic : IClass1Logic
{
private readonly IClass1Repository _repo;
public Class1Logic(IClass1Repository repository)
{
_repo = repository;
}
public async Task<bool> AddClass1ItemAsync(Class1 item)
{
_repo.Add(item);
bool status = await _repo.SaveAsync();
return status;
}
public async Task<Class1> GetClass1ItemAsync(int id)
{
return await _repo.GetAsync(id);
}
}
public class Class2Logic : IClass1Logic
{
private readonly IClass2Repository _repo;
public Class2Logic(IClass2Repository repository)
{
_repo = repository;
}
public async Task<bool> AddClass2ItemAsync(Class2 item)
{
_repo.Add(item);
bool status = await _repo.SaveAsync();
return status;
}
public async Task<Class2> GetClass2ItemAsync(int id)
{
return await _repo.GetAsync(id);
}
}
的ViewModels:
public class Class1Model
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Class2Model
{
public int Id { get; internal set; }
public string Name { get; set; }
public int Class1Id { get; set; }
public string Class1Name { get; internal set; }
}
控制器:
有两个类似于Class1Controller和Class2Controller的控制器。两者都有CRUD操作。
[RoutePrefix("api/class1items")]
public class Class1Controller : ApiController
{
private readonly IClass1Logic _class1Logic;
private ModelFactory TheFactory;
public Class1Controller(IClass1Logic class1Logic)
{
_class1Logic = class1Logic;
TheFactory = new ModelFactory();
}
[Route("")]
public async Task<IHttpActionResult> Post(Class1Model class1Model)
{
var item = TheFactory.Parse(class1Model);
bool result = await _class1Logic.AddClassItemAsync(item);
if (!result)
{
return BadRequest("Error");
}
string uri = Url.Link("GetLabById", new { id = item.Id });
return Created(uri, TheFactory.Create(item));
}
[Route("{id:int}", Name = "GetClass1ItemById")]
public async Task<IHttpActionResult> GetClass1Item(int id)
{
Class1 item = await _class1Logic.GetClassItemAsync(id);
if (item == null)
{
return NotFound();
}
return Ok(TheFactory.Create(item));
}
}
[RoutePrefix("api/class2items")]
public class Class2Controller : ApiController
{
private readonly IClass2Logic _class2Logic;
private ModelFactory TheFactory;
public Class2Controller(IClass2Logic class2Logic)
{
_class2Logic = class2Logic;
TheFactory = new ModelFactory();
}
[Route("")]
public async Task<IHttpActionResult> Post(Class2Model class2Model)
{
var item = TheFactory.Parse(class2Model);
***//Here item should include Class1 object even if user give ClassId in class2Model***
bool result = await _class2Logic.AddClassItemAsync(item);
if (!result)
{
return BadRequest("Error");
}
string uri = Url.Link("GetClass2ItemById", new { id = item.Id });
return Created(uri, TheFactory.Create(item));
}
}
Class1没有任何依赖。所以所有操作都很好。在Class2Controller post方法中,我得到了如下的模型对象来创建Class2。
{
"id": 0,
"name": "string",
"class1Id": 1
}
理解:
我需要在创建记录后将此viewmodel返回给用户。记录创建成功,但是当映射到viewmodel时,我得到了null异常,因为Class1对象不在Class2对象中。
为了获得包含class1对象的Class2对象,我需要在请求对象中给出class1Object。
为此,我需要在请求对象中找到Class1Id的Class1对象。
ViewMapper代码:
public class ModelFactory
{
public Class1Model Create(Class1 item)
{
return new Class1Model
{
Id = item.Id,
Name = item.Name
};
}
public Class2Model Create(Class2 item)
{
return new Class2Model
{
Id = item.Id,
Name = item.Name,
Class1Id = item.class1.Id,
Class1Name = item.class1.Name
};
}
public Class1 Parse(Class1Model modelItem)
{
return new Class1
{
Id = modelItem.Id,
Name = modelItem.Name
};
}
public Class2 Parse(Class2Model modelItem)
{
return new Class2
{
Id = modelItem.Id,
Name = modelItem.Name,
Class1Id = modelItem.Class1Id,
***/*Issue Place*/
//class1 = Need to set property by getting object using modelItem.Class1Id***
};
}
}
问题:
现在我需要通过传递Class1Id来调用Class1Controller的get方法。
如何打电话,这是正确的吗?还是我的设计不好?
这是最初的情况。如果我的Class3再次同时具有Class1和Class2,我需要调用Class1和Class2的方法。
请帮助在这种情况下找到正确的解决方案
注意:我在问题区域添加了评论
答案 0 :(得分:0)
好吧,只是要解决此问题,您需要在保存后手动调用class Program
{
static void Main(string[] args)
{
CreateFileStream();
byte[] array1 = new byte[1191980];
byte[] array2 = new byte[1191936];
byte[] array3 = new byte[1191936];
byte[] array4 = new byte[85138]; //Larger size - Can change file name
//byte[] array4 = new byte[79462]; //Smaller size - Cannot change file name
}//Breakpoint here, try and change the file name C:\FileName.wav to something else
private static void CreateFileStream()
{
FileStream fileStream = new FileStream(@"C:\FileName.wav", FileMode.Open, FileAccess.Read, FileShare.Read);
}
}
。然而,这看起来不太好。
更优雅的解决方法:
1)如果您需要填写def firstRepeatedWord(string)
h_data = Hash.new(0)
string.split(" ").each{|x| h_data[x] +=1}
h_data.key(h_data.values.max)
end
字段,请在获取数据时使用_class1Logic.GetClass1ItemAsync
(在存储库中):Class2.Class1
。
2)你也可以打开LazyLoading for EF - 我认为它应该适用于你的情况。
3)将class1Repo注入class2Logic并在保存后修复class1引用 - 如果你不想启用延迟加载或者在save方法之后将项目与上下文分离
关于设计的想法:
我建议您查看Automapper或simular库而不是Include
,其中您将拥有所有映射逻辑
编辑:关于通用存储库:您可以修改dbContext.Set<Class2>().Include(c => c.class1)
方法
ModelFactory
IEntity界面:
GetAsync
通过此实现,您可以使用
public async Task<T> GetAsync<T>(int id, params Expression<Func<T, object>>[] includes)
where T: class, IEntity
{
var query = context.Set<T>().AsQueryable();
if (includes.Length > 0)
{
query = includes.Aggregate(query,
(current, include) => current.Include(include));
}
return await query.FirstOrDefaultAsync(x => x.Id == id);
}